diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/COPYING linux/COPYING
--- linux.orig/COPYING	Tue Oct  9 22:00:06 2001
+++ linux/COPYING	Tue May 28 22:39:12 2002
@@ -307,7 +307,7 @@
 the "copyright" line and a pointer to where the full notice is found.
 
     <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) 19yy  <name of author>
+    Copyright (C) <year>  <name of author>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -329,7 +329,7 @@
 If the program is interactive, make it output a short notice like this
 when it starts in an interactive mode:
 
-    Gnomovision version 69, Copyright (C) 19yy name of author
+    Gnomovision version 69, Copyright (C) year name of author
     Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
     This is free software, and you are welcome to redistribute it
     under certain conditions; type `show c' for details.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/CREDITS linux/CREDITS
--- linux.orig/CREDITS	Mon Feb 25 19:37:50 2002
+++ linux/CREDITS	Tue May 28 22:39:18 2002
@@ -586,8 +586,15 @@
 S: University of Michigan
 S: Ann Arbor, MI
 
+N: Michael Cornwell
+E: cornwell@acm.org
+D: Original designer and co-author of ATA Taskfile
+D: Kernel module SMART utilities
+S: Santa Cruz, California
+S: USA
+
 N: Kees Cook
-E: cook@cpoint.net
+E: kees@outflux.net
 W: http://outflux.net/
 P: 1024D/17063E6D 9FA3 C49C 23C9 D1BC 2E30  1975 1FFF 4BA9 1706 3E6D
 D: Minor updates to SCSI code for the Communications type
@@ -628,6 +635,11 @@
 S: NN1 3QT
 S: United Kingdom
 
+N: Stephane Dalton
+E: sdalton@videotron.ca
+D: Tieman Voyager USB Braille display driver.
+S: Québec, Canada
+
 N: Uwe Dannowski
 E: Uwe.Dannowski@ira.uka.de
 W: http://i30www.ira.uka.de/~dannowsk/
@@ -734,6 +746,11 @@
 W: http://www.fsmlabs.com/linuxppcbk.html
 D: PowerPC
 
+N: Stéphane Doyon
+E: s.doyon@videotron.ca
+D: Tieman Voyager USB Braille display driver.
+S: Québec, Canada
+
 N: Oleg Drokin
 E: green@ccssu.crimea.ua
 W: http://www.ccssu.crimea.ua/~green
@@ -1184,22 +1201,19 @@
 
 N: Andre Hedrick
 E: andre@linux-ide.org
-E: andre@aslab.com
-E: andre@suse.com
+E: andre@linuxdiskcert.org
 W: http://www.linux-ide.org/
+W: http://www.linuxdiskcert.org/
 D: Random SMP kernel hacker...
 D: Uniform Multi-Platform E-IDE driver
 D: Active-ATA-Chipset maddness..........
-D: Ultra DMA 100/66/33
-D: ATA-Disconnect
+D: Ultra DMA 133/100/66/33 w/48-bit Addressing
+D: ATA-Disconnect, ATA-TCQ
 D: ATA-Smart Kernel Daemon
+D: Serial ATA
+D: ATA Command Block and Taskfile
 S: Linux ATA Development (LAD)
 S: Concord, CA
-S: ASL, Inc. 1-877-ASL-3535
-S: 1757 Houret Court, Milpitas, CA 95035
-S: SuSE Linux, Inc.
-S: 580 Second Street, Suite 210  Oakland, CA  94607
-S: USA
 
 N: Jochen Hein
 E: jochen@jochen.org
@@ -1574,8 +1588,10 @@
 S: Luxembourg
 
 N: Gerd Knorr
-E: kraxel@goldbach.in-berlin.de
-D: SCSI CD-ROM driver hacking, vesafb, v4l, minor bug fixes
+W: http://bytesex.org
+E: kraxel@bytesex.org
+E: kraxel@suse.de
+D: video4linux, bttv, vesafb, some scsi, misc fixes
 
 N: Harald Koenig
 E: koenig@tat.physik.uni-tuebingen.de
@@ -1652,6 +1668,13 @@
 S: San Antonio, Texas 78269-1886
 S: USA
 
+N: Denis O. Kropp
+E: dok@directfb.org
+D: NeoMagic framebuffer driver
+S: Badensche Str. 46
+S: 10715 Berlin
+S: Germany
+
 N: Andrzej M. Krzysztofowicz
 E: ankry@mif.pg.gda.pl
 D: Some 8-bit XT disk driver and devfs hacking 
@@ -1895,13 +1918,14 @@
 S: USA
 
 N: Petko Manolov
-E: petkan@dce.bg
-D: USB ethernet (pegasus) driver
-D: optimizing i[45]86 string routines
-D: i386 task swithing hacks
-S: 5, Vrah Mancho str.
-S: 1324 Sofia
-S: Bulgaria
+E: petkan@users.sourceforge.net
+D: USB ethernet pegasus/pegasus-II driver
+D: USB ethernet rtl8150 driver
+D: i[45]86 optimized string routines
+D: i386 task switching hacks
+S: 482 Shadowgraph Dr.
+S: San Jose, CA  95110
+S: USA
 
 N: Martin Mares
 E: mj@ucw.cz
@@ -2130,6 +2154,10 @@
 S: Fullarton 5063
 S: South Australia
 
+N. Wolfgang Muees
+E: wmues@nexgo.de
+D: Auerswald USB driver
+
 N: Ian A. Murdock
 E: imurdock@gnu.ai.mit.edu
 D: Creator of Debian distribution
@@ -2513,6 +2541,7 @@
 
 N: Thiago Berlitz Rondon
 E: maluco@mileniumnet.com.br
+W: http://vivaldi.linuxms.com.br/~maluco
 D: Miscellaneous kernel hacker
 S: R. Anhanguera, 1487 - Ipiranga
 S: 79080-740 - Campo Grande - Mato Grosso do Sul
@@ -3265,9 +3294,10 @@
 S: USA
 
 N: Richard Zidlicky
-E: rdzidlic@geocities.com,rdzidlic@cip.informatik.uni-erlangen.de
-W: http://www.geocities.com/SiliconValley/Bay/2602/
+E: rz@linux-m68k.org, rdzidlic@geocities.com
+W: http://www.geocities.com/rdzidlic
 D: Q40 port - see arch/m68k/q40/README
+D: various m68k hacks
 S: Germany
 
 N: Werner Zimmermann
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/Changes linux/Documentation/Changes
--- linux.orig/Documentation/Changes	Fri Dec 21 17:41:53 2001
+++ linux/Documentation/Changes	Tue May 28 22:39:24 2002
@@ -31,7 +31,7 @@
 Eine deutsche Version dieser Datei finden Sie unter
 <http://www.stefan-winter.de/Changes-2.4.0.txt>.
 
-Last updated: May 9, 2001
+Last updated: February 13, 2002
 
 Chris Ricker (kaboom@gatech.edu or chris.ricker@genetics.utah.edu).
 
@@ -54,7 +54,8 @@
 o  util-linux             2.10o                   # fdformat --version
 o  modutils               2.4.2                   # insmod -V
 o  e2fsprogs              1.25                    # tune2fs
-o  reiserfsprogs          3.x.0j                  # reiserfsck 2>&1|grep reiserfsprogs
+o  jfsutils               1.0.12                  # fsck.jfs -V
+o  reiserfsprogs          3.x.1b                  # reiserfsck 2>&1|grep reiserfsprogs
 o  pcmcia-cs              3.1.21                  # cardmgr -V
 o  PPP                    2.4.0                   # pppd --version
 o  isdn4k-utils           3.1pre1                 # isdnctrl 2>&1|grep version
@@ -70,9 +71,9 @@
 necessarily to users of other CPUs. Users of other CPUs should obtain
 information about their gcc version requirements from another source.
 
-The recommended compiler for the kernel is gcc 2.95.3 or .4, and it
+The recommended compiler for the kernel is gcc 2.95.x (x >= 3), and it
 should be used when you need absolute stability. You may use gcc 3.0.x
-instead if you wish, although it may cause problems. Later  versions of gcc 
+instead if you wish, although it may cause problems. Later versions of gcc 
 have not received much testing for Linux kernel compilation, and there are 
 almost certainly bugs (mainly, but not exclusively, in the kernel) that
 will need to be fixed in order to use these compilers. In any case, using
@@ -106,14 +107,14 @@
 your kernel.  This change does, however, mean that you need a recent
 release of binutils.
 
-If you can, upgrade to the latest 2.9.5 or 2.10 binutils release.  Older
+If you can, upgrade to the latest 2.9.5 or 2.1x binutils release.  Older
 releases such as 2.8, 2.8.xx, and the FSF's 2.9.1 should be avoided if
 at all possible.  The later releases of 2.9.1.0.x (anything where x >= 22)
 can and do compile the kernel properly, but there are many benefits in
-upgrading to 2.9.5 or 2.10 if you're up to it.
+upgrading to 2.9.5 or 2.1x if you're up to it.
 
-System utils
-============
+System utilities
+================
 
 Architectural changes
 ---------------------
@@ -171,6 +172,16 @@
 The latest version of e2fsprogs fixes several bugs in fsck and
 debugfs.  Obviously, it's a good idea to upgrade.
 
+JFSutils
+--------
+
+The jfsutils package contains the utilities for the file system.
+The following utilities are available:
+o fsck.jfs - initiate replay of the transaction log, and check
+  and repair a JFS formatted partition.
+o mkfs.jfs - create a JFS formatted partition.
+o other file system utilities are also available in this package.
+
 Reiserfsprogs
 -------------
 
@@ -267,8 +278,8 @@
 Getting updated software
 ========================
 
-Compilers
-*********
+Kernel compilation
+******************
 
 egcs 1.1.2 (gcc 2.91.66)
 ------------------------
@@ -276,32 +287,22 @@
 
 gcc 2.95.3
 ----------
-o  <ftp://ftp.gnu.org/pub/gnu/gcc/gcc-2.95.3.tar.gz>
-
-Gnu Make
-********
+o  <ftp://ftp.gnu.org/gnu/gcc/gcc-2.95.3.tar.gz>
 
 Make 3.77
 ---------
 o  <ftp://ftp.gnu.org/gnu/make/make-3.77.tar.gz>
 
 Binutils
-********
-
-2.9.1 series
-------------
-o  <ftp://ftp.valinux.com/pub/support/hjl/binutils/2.9.1/binutils-2.9.1.0.25.tar.gz>
-
-2.9.5 and 2.10 series
----------------------
-o  <ftp://ftp.valinux.com/pub/support/hjl/binutils/>
+--------
+o  <ftp://ftp.kernel.org/pub/linux/devel/binutils/>
 
 System utilities
 ****************
 
 Util-linux
 ----------
-o  <ftp://ftp.kernel.org/pub/linux/utils/util-linux/util-linux-2.10o.tar.gz>
+o  <ftp://ftp.kernel.org/pub/linux/utils/util-linux/>
 
 Ksymoops
 --------
@@ -319,9 +320,13 @@
 ---------
 o  <http://prdownloads.sourceforge.net/e2fsprogs/e2fsprogs-1.25.tar.gz>
 
+JFSutils
+---------
+o  <http://oss.software.ibm.com/jfs/>
+
 Reiserfsprogs
 -------------
-o  <ftp://ftp.namesys.com/pub/reiserfsprogs/reiserfsprogs-3.x.0j.tar.gz>
+o  <ftp://ftp.namesys.com/pub/reiserfsprogs/reiserfsprogs-3.x.1b.tar.gz>
 
 LVM toolset
 -----------
@@ -345,10 +350,10 @@
 
 Powertweak
 ----------
-o  <http://powertweak.sourceforge.net>
+o  <http://powertweak.sourceforge.net/>
 
-Network
-*******
+Networking
+**********
 
 PPP
 ---
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/Configure.help linux/Documentation/Configure.help
--- linux.orig/Documentation/Configure.help	Mon Feb 25 19:37:51 2002
+++ linux/Documentation/Configure.help	Tue May 28 22:39:31 2002
@@ -490,6 +490,23 @@
 
   Most users will answer N here.
 
+Micro Memory MM5415 Battery Backed RAM support (EXPERIMENTAL)
+CONFIG_BLK_DEV_UMEM
+  Saying Y here will include support for the MM5415 family of
+  battery backed (Non-volatile) RAM cards.
+  http://www.umem.com/
+
+  The cards appear as block devices that can be partitioned into
+  as many as 15 partitions.
+
+  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. The module will be
+  called umem.o.
+
+  The umem driver has been allocated block major number 116.
+  See Documentation/devices.txt for recommended device naming.
+
 Network block device support
 CONFIG_BLK_DEV_NBD
   Saying Y here will allow your computer to be a client for network
@@ -723,6 +740,59 @@
   say M here and read <file:Documentation/modules.txt>.  The module
   will be called ide-floppy.o.
 
+AWARD Bios Work-Around
+CONFIG_IDEDISK_STROKE
+  Should you have a system w/ an AWARD Bios and your drives are larger
+  than 32GB and it will not boot, one is required to perform a few OEM
+  operations first.  The option is called "STROKE" because it allows
+  one to "soft clip" the drive to work around a barrier limit.  For
+  Maxtor drives it is called "jumpon.exe".  Please search Maxtor's
+  web-site for "JUMPON.EXE".  IBM has a similar tool at:
+  <http://www.storage.ibm.com/hdd/support/download.htm>.
+
+  If you are unsure, say N here.
+
+Raw Access to Media
+CONFIG_IDE_TASK_IOCTL
+  This is a direct raw access to the media.  It is a complex but
+  elegant solution to test and validate the domain of the hardware and
+  perform below the driver data recover if needed.  This is the most
+  basic form of media-forensics.
+
+  If you are unsure, say N here.
+
+Use Taskfile I/O
+CONFIG_IDE_TASKFILE_IO
+  This is the "Jewel" of the patch.  It will go away and become the new
+  driver core.  Since all the chipsets/host side hardware deal w/ their
+  exceptions in "their local code" currently, adoption of a
+  standardized data-transport is the only logical solution.
+  Additionally we packetize the requests and gain rapid performance and
+  a reduction in system latency.  Additionally by using a memory struct
+  for the commands we can redirect to a MMIO host hardware in the next
+  generation of controllers, specifically second generation Ultra133
+  and Serial ATA.
+
+  Since this is a major transition, it was deemed necessary to make the
+  driver paths buildable in separtate models.  Therefore if using this
+  option fails for your arch then we need to address the needs for that
+  arch.
+
+  If you want to test this functionality, say Y here.
+
+Force DMA
+CONFIG_BLK_DEV_IDEDMA_FORCED
+  This is an old piece of lost code from Linux 2.0 Kernels.
+
+  Generally say N here.
+
+DMA Only on Disks
+CONFIG_IDEDMA_ONLYDISK
+  This is used if you know your ATAPI Devices are going to fail DMA
+  Transfers.
+
+  Generally say N here.
+
 SCSI emulation support
 CONFIG_BLK_DEV_IDESCSI
   This will provide SCSI host adapter emulation for IDE ATAPI devices,
@@ -747,6 +817,14 @@
   If both this SCSI emulation and native ATAPI support are compiled
   into the kernel, the native support will be used.
 
+Use the NOOP Elevator (WARNING)
+CONFIG_BLK_DEV_ELEVATOR_NOOP
+  If you are using a raid class top-level driver above the ATA/IDE core,
+  one may find a performance boost by preventing a merging and re-sorting
+  of the new requests.
+
+  If unsure, say N.
+
 ISA-PNP EIDE support
 CONFIG_BLK_DEV_ISAPNP
   If you have an ISA EIDE card that is PnP (Plug and Play) and
@@ -1028,7 +1106,7 @@
 
   If unsure, say N.
 
-HPT366 chipset support
+HPT366/368/370 chipset support
 CONFIG_BLK_DEV_HPT366
   HPT366 is an Ultra DMA chipset for ATA-66.
   HPT368 is an Ultra DMA chipset for ATA-66 RAID Based.
@@ -1136,9 +1214,15 @@
 
 SiS5513 chipset support
 CONFIG_BLK_DEV_SIS5513
-  This driver ensures (U)DMA support for SIS5513 chipset based
-  mainboards. SiS620/530 UDMA mode 4, SiS5600/5597 UDMA mode 2, all
-  other DMA mode 2 limited chipsets are unsupported to date.
+  This driver ensures (U)DMA support for SIS5513 chipset family based
+  mainboards.
+
+  The following chipsets are supported:
+  ATA16:  SiS5511, SiS5513
+  ATA33:  SiS5591, SiS5597, SiS5598, SiS5600
+  ATA66:  SiS530, SiS540, SiS620, SiS630, SiS640
+  ATA100: SiS635, SiS645, SiS650, SiS730, SiS735, SiS740,
+          SiS745, SiS750
 
   If you say Y here, you need to say Y to "Use DMA by default when
   available" as well.
@@ -1982,6 +2066,11 @@
   which allows for more memory.  Your system is most probably
   running in M-Mode, so you should say N here.
 
+Lasi ethernet
+CONFIG_LASI_82596
+  Say Y here to support the on-board Intel 82596 ethernet controller
+  built into Hewlett-Packard PA-RISC machines.
+
 MIPS JAZZ onboard SONIC Ethernet support
 CONFIG_MIPS_JAZZ_SONIC
   This is the driver for the onboard card of MIPS Magnum 4000,
@@ -2513,6 +2602,19 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+Local NAT support
+CONFIG_IP_NF_NAT_LOCAL
+  This option enables support for NAT of locally originated connections. 
+  Enable this if you need to use destination NAT on connections
+  originating from local processes on the nat box itself.
+
+  Please note that you will need a recent version (>= 1.2.6a)
+  of the iptables userspace program in order to use this feature.
+  See http://www.iptables.org/ for download instructions.
+
+  If unsure, say 'N'.
+
+
 Full NAT (Network Address Translation)
 CONFIG_IP_NF_NAT
   The Full NAT option allows masquerading, port forwarding and other
@@ -2824,14 +2926,6 @@
 
   If unsure, say N.
 
-HCI EMU (virtual device) driver
-CONFIG_BLUEZ_HCIEMU
-  Bluetooth Virtual HCI device driver.
-  This driver is required if you want to use HCI Emulation software.
-
-  Say Y here to compile support for Virtual HCI devices into the
-  kernel or say M to compile it as module (hci_usb.o).
-
 # Choice: alphatype
 Alpha system type
 CONFIG_ALPHA_GENERIC
@@ -3110,14 +3204,6 @@
   say N here to save some memory. You can also say Y if you have an
   "intelligent" multiport card such as Cyclades, Digiboards, etc.
 
-Support for serial ports defined by ACPI tables
-CONFIG_SERIAL_ACPI
-  Legacy free machines may not have serial ports at the legacy COM1, 
-  COM2 etc addresses. Serial ports on such machines are described by
-  the ACPI tables SPCR (Serial Port Console Redirection) table and 
-  DBGP (Debug Port) table. Say Y here if you want to include support
-  for these serial ports.
-
 Support for sharing serial interrupts
 CONFIG_SERIAL_SHARE_IRQ
   Some serial boards have hardware support which allows multiple dumb
@@ -3167,6 +3253,13 @@
   via the file /proc/rtc and its behaviour is set by various ioctls on
   /dev/rtc.
 
+Indy/I2 Hardware Watchdog
+CONFIG_INDYDOG
+  Hardwaredriver for the Indy's/I2's watchdog. This is a
+  watchdog timer that will reboot the machine after a 60 second 
+  timer expired and no process has written to /dev/watchdog during
+  that time.
+
 Support the Bell Technologies HUB6 card
 CONFIG_HUB6
   Say Y here to enable support in the dumb serial driver to support
@@ -3307,6 +3400,10 @@
   You should say Y here if you use XFree86 3.3.6 or 4.x and want to
   use GLX or DRI.  If unsure, say N.
 
+CONFIG_AGP_HP_ZX1
+  This option gives you AGP GART support for the HP ZX1 chipset
+  for IA64 processors.
+
 Support for ISA-bus hardware
 CONFIG_ISA
   Find out whether you have ISA slots on your motherboard.  ISA is the
@@ -4207,6 +4304,16 @@
   This driver supports the L7200 Color LCD.
   Say Y if you want graphics support.
 
+NeoMagic display support (EXPERIMENTAL)
+CONFIG_FB_NEOMAGIC
+  This driver supports notebooks with NeoMagic PCI chips.
+  Say Y if you have such a graphics card. 
+
+  The 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 neofb.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
+
 PowerMac "control" frame buffer device support
 CONFIG_FB_CONTROL
   This driver supports a frame buffer for the graphics adapter in the
@@ -4414,7 +4521,8 @@
 CONFIG_FB_MATROX
   Say Y here if you have a Matrox Millennium, Millennium II, Mystique,
   Mystique 220, Productiva G100, Mystique G200, Millennium G200,
-  Marvel G200 video, G400, G450, or G550 card in your box.
+  Matrox G400, G450 or G550 card in your box. At this time, support for 
+  the G-series digital output is almost non-existant.
 
   This driver is also available as a module ( = code which can be
   inserted and removed from the running kernel whenever you want).
@@ -4453,6 +4561,10 @@
   "I2C support" and "I2C bit-banging support" in the character devices
   section, and then to "Matrox I2C support" and "G400 second head
   support" here in the framebuffer section.
+  
+  If you have G550, you must also compile support for G450/G550 secondary
+  head into kernel, otherwise picture will be shown only on the output you
+  are probably not using...
 
   If you need support for G450 or G550 secondary head, say Y to
   "Matrox G450/G550 second head support" below.
@@ -4503,7 +4615,8 @@
 Matrox G450 second head support
 CONFIG_FB_MATROX_G450
   Say Y or M here if you want to use a secondary head (meaning two
-  monitors in parallel) on G450 or G550.
+  monitors in parallel) on G450, or if you are using analog output
+  of G550.
 
   If you compile it as module, two modules are created,
   matroxfb_crtc2.o and matroxfb_g450.o. Both modules are needed if you
@@ -4645,6 +4758,12 @@
   The IMS Twin Turbo is a PCI-based frame buffer card bundled with
   many Macintosh and compatible computers.
 
+CONFIG_FB_TX3912
+  The TX3912 is a Toshiba RISC processor based on the MIPS 3900 core;
+  see <http://www.toshiba.com/taec/components/Generic/risc/tx3912.htm>.
+
+  Say Y here to enable kernel support for the on-board framebuffer.
+
 Virtual Frame Buffer support (ONLY FOR TESTING!)
 CONFIG_FB_VIRTUAL
   This is a `virtual' frame buffer device. It operates on a chunk of
@@ -4796,6 +4915,13 @@
   bits per pixel packed pixels on Mac. It supports variable font
   widths for low resolution screens.
 
+Permedia3 support (EXPERIMENTAL)
+CONFIG_FB_PM3
+  This is the frame buffer device driver for the 3DLabs Permedia3
+  chipset, used in Formac ProFormance III, 3DLabs Oxygen VX1 &
+  similar boards, 3DLabs Permedia3 Create!, Appian Jeronimo 2000
+  and maybe other boards.
+
 HGA monochrome support
 CONFIG_FBCON_HGA
   This is the low level frame buffer console driver for Hercules mono
@@ -5434,18 +5560,19 @@
   (see ipchains(8), "-m" argument).
 
 AppleTalk interfaces support
-CONFIG_APPLETALK
-  AppleTalk is the way Apple computers speak to each other on a
-  network. If your Linux box is connected to such a network and you
-  want to join the conversation, say Y.
+CONFIG_DEV_APPLETALK
+  AppleTalk is the protocol that Apple computers can use to communicate
+  on a network.  If your Linux box is connected to such a network, and wish
+  to do IP over it, or you have a LocalTalk card and wish to use it to
+  connect to the AppleTalk network, say Y.
 
 AppleTalk protocol support
 CONFIG_ATALK
-  AppleTalk is the way Apple computers speak to each other on a
-  network.  If your Linux box is connected to such a network and you
-  want to join the conversation, say Y.  You will need to use the
-  netatalk package so that your Linux box can act as a print and file
-  server for Macs as well as access AppleTalk printers.  Check out
+  AppleTalk is the protocol that Apple computers can use to communicate
+  on a network.  If your Linux box is connected to such a network and you
+  wish to connect to it, say Y.  You will need to use the netatalk package
+  so that your Linux box can act as a print and file server for Macs as
+  well as access AppleTalk printers.  Check out
   <http://www.zettabyte.net/netatalk/> on the WWW for details.
   EtherTalk is the name used for AppleTalk over Ethernet and the
   cheaper and slower LocalTalk is AppleTalk over a proprietary Apple
@@ -6099,6 +6226,19 @@
   briefly removed during revalidation. If you say Y here, packets to
   such neighbours are silently discarded instead.
 
+RFC1483/2684 Bridged protocols
+CONFIG_ATM_BR2684
+  ATM PVCs can carry ethernet PDUs according to rfc2684 (formerly 1483)
+  This device will act like an ethernet from the kernels point of view,
+  with the traffic being carried by ATM PVCs (currently 1 PVC/device).
+  This is sometimes used over DSL lines.  If in doubt, say N.
+
+Per-VC IP filter kludge
+CONFIG_ATM_BR2684_IPFILTER
+  This is an experimental mechanism for users who need to terminating a
+  large number of IP-only vcc's.  Do not enable this unless you are sure
+  you know what you are doing.
+
 LAN Emulation (LANE) support
 CONFIG_ATM_LANE
   LAN Emulation emulates services of existing LANs across an ATM
@@ -6394,6 +6534,18 @@
   boards supported by this driver, and for further information
   on the use of this driver.
 
+SCSI tape drive support for Smart Array 5xxx
+CONFIG_CISS_SCSI_TAPE
+  When enabled (Y), this option allows SCSI tape drives and SCSI medium
+  changers (tape robots) to be accessed via a Compaq 5xxx array
+  controller.  (See Documentation/cciss.txt for more details.)
+
+  "SCSI support" and "SCSI tape support" must also be enabled for this
+  option to work.
+
+  When this option is disabled (N), the SCSI portion of the driver
+  is not compiled.
+
 QuickNet Internet LineJack/PhoneJack support
 CONFIG_PHONE_IXJ
   Say M if you have a telephony card manufactured by Quicknet
@@ -6411,6 +6563,12 @@
   If you do not have any Quicknet telephony cards, you can safely
   say N here.
 
+QuickNet Internet LineJack/PhoneJack PCMCIA support
+CONFIG_PHONE_IXJ_PCMCIA
+  Say Y here to configure in PCMCIA service support for the Quicknet
+  cards manufactured by Quicknet Technologies, Inc.  This builds an
+  additional support module for the PCMCIA version of the card.
+
 FORE Systems 200E-series
 CONFIG_ATM_FORE200E_MAYBE
   This is a driver for the FORE Systems 200E-series ATM adapter
@@ -7720,6 +7878,12 @@
   The module will be called qlogicfc.o.  If you want to compile it as
   a module, say M here and read <file:Documentation/modules.txt>.
 
+Include loadable firmware in driver
+CONFIG_SCSI_QLOGIC_FC_FIRMWARE
+  Say Y to include ISP2100 Fabric Initiator/Target Firmware, with
+  expanded LUN addressing and FcTape (FCP-2) support, in the
+  Qlogic QLA 1280 driver. This is required on some platforms.
+
 Qlogic QLA 1280 SCSI support
 CONFIG_SCSI_QLOGIC_1280
   Say Y if you have a QLogic ISP1x80/1x160 SCSI host adapter.
@@ -8882,6 +9046,19 @@
   it as a module, say M here and read
   <file:Documentation/modules.txt>. If unsure, say N.
 
+Xircom CardBus support (new driver)
+CONFIG_PCMCIA_XIRCOM
+  This driver is for the Digital "Tulip" Ethernet CardBus adapters.
+  It should work with most DEC 21*4*-based chips/ethercards, as well
+  as with work-alike chips from Lite-On (PNIC) and Macronix (MXIC) and
+  ASIX.
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called xircom_cb.o.  If you want to compile
+  it as a module, say M here and read
+  <file:Documentation/modules.txt>. If unsure, say N.
+
 PCMCIA Wireless LAN
 CONFIG_NET_PCMCIA_RADIO
   Say Y here if you would like to use a PCMCIA (PC-card) device to
@@ -8925,6 +9102,14 @@
   Support for these adaptors is so far still incomplete and buggy.
   You have been warned.
 
+Prism 2.5 PCI 802.11b adaptor support
+CONFIG_PCI_HERMES
+  Enable support for PCI and mini-PCI 802.11b wireless NICs based on
+  the Prism 2.5 chipset.  These are true PCI cards, not the 802.11b
+  PCMCIA cards bundled with PCI<->PCMCIA adaptors which are also
+  common.  Some of the built-in wireless adaptors in laptops are of
+  this variety.
+
 Hermes support (Orinoco/WavelanIEEE/PrismII/Symbol 802.11b cards)
 CONFIG_PCMCIA_HERMES
   A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
@@ -9132,6 +9317,28 @@
   If you want to do that, say M here. The module will be called
   sealevel.o.
 
+TMPTX3912/PR31700 serial port support
+CONFIG_SERIAL_TX3912
+  The TX3912 is a Toshiba RISC processor based o the MIPS 3900 core;
+  see <http://www.toshiba.com/taec/components/Generic/risc/tx3912.htm>.
+  Say Y here to enable kernel support for the on-board serial port.
+
+Console on TMPTX3912/PR31700 serial port
+CONFIG_SERIAL_TX3912_CONSOLE
+  The TX3912 is a Toshiba RISC processor based o the MIPS 3900 core;
+  see <http://www.toshiba.com/taec/components/Generic/risc/tx3912.htm>.
+  Say Y here to direct console I/O to the on-board serial port.
+
+Enable Au1000 serial console
+CONFIG_AU1000_SERIAL_CONSOLE
+  If you have an Alchemy AU1000 processor (MIPS based) and you want
+  to use a console on a serial port, say Y.  Otherwise, say N.
+
+Enable Au1000 UART Support
+CONFIG_AU1000_UART
+  If you have an Alchemy AU1000 processor (MIPS based) and you want
+  to use serial ports, say Y.  Otherwise, say N.
+
 SyncLink HDLC/SYNCPPP support
 CONFIG_SYNCLINK_SYNCPPP
   Enables HDLC/SYNCPPP support for the SyncLink WAN driver.
@@ -9588,6 +9795,21 @@
   performance will be written to /proc/net/profile. If you don't know
   what it is about, you don't need it: say N.
 
+Network packet generator
+CONFIG_NET_PKTGEN
+  This module will inject preconfigured packets, at a configurable
+  rate, out of a given interface.  It is used for network interface
+  stress testing and performance analysis.  If you don't understand
+  what was just said, you don't need it: say N.
+
+  Documentation on how to use the packet generator can be found
+  at <file:Documentation/networking/pktgen.txt>.
+
+  This code is also available as a module called pktgen.o ( = code
+  which can be inserted in and removed from the running kernel
+  whenever you want).  If you want to compile it as a module, say M
+  here and read <file:Documentation/modules.txt>.
+
 Wan interfaces support
 CONFIG_WAN
   Wide Area Networks (WANs), such as X.25, frame relay and leased
@@ -9893,6 +10115,20 @@
   <file:Documentation/modules.txt>.  The module will be called
   i810-tco.o.
 
+SliceCOM/PciCOM board support
+CONFIG_COMX_HW_MUNICH
+  Hardware driver for the 'SliceCOM' (channelized E1) and 'PciCOM'
+  boards (X21) from the MultiGate family.
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called comx-hw-munich.o. If you want to compile it
+  as a module, say M here and read <file:Documentation/modules.txt>.
+
+  Read linux/Documentation/networking/slicecom.txt for help on
+  configuring and using SliceCOM interfaces. Further info on these cards
+  can be found at http://www.itc.hu or <info@itc.hu>.
+
 Support for HDLC and syncPPP protocols on MultiGate boards
 CONFIG_COMX_PROTO_PPP
   Cisco-HDLC and synchronous PPP protocol driver for all MultiGate
@@ -10367,6 +10603,15 @@
   Support for the Sun GEM chip, aka Sun GigabitEthernet/P 2.0.  See also
   <http://www.sun.com/products-n-solutions/hardware/docs/pdf/806-3985-10.pdf>.
 
+Broadcom Tigon3 support
+CONFIG_TIGON3
+  This driver supports Broadcom Tigon3 based gigabit Ethernet cards.
+
+  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 <file:Documentation/modules.txt>.  This is
+  recommended.  The module will be called tg3.o.
+
 MyriCOM Gigabit Ethernet support
 CONFIG_MYRI_SBUS
   This driver supports MyriCOM Sbus gigabit Ethernet cards.
@@ -11089,6 +11334,12 @@
   cards. Specifications and data at
   <http://www.myson.com.hk/mtd/datasheet/>.
 
+LP486E on board Ethernet
+CONFIG_LP486E
+  Say Y here to support the 82596-based on-board Ethernet controller
+  for the Panther motherboard, which is one of the two shipped in the
+  Intel Professional Workstation.
+
 ICL EtherTeam 16i/32 support
 CONFIG_ETH16I
   If you have a network (Ethernet) card of this type, say Y and read
@@ -11439,6 +11690,24 @@
   The module will be called smctr.o. If you want to compile it
   as a module, say M here and read <file:Documentation/modules.txt>.
 
+3COM 3C359 Token Link Velocity XL PCI adapter support
+CONFIG_3C359
+  This is support for the 3Com PCI Velocity XL cards, specifically
+  the 3Com 3C359, please note this is not for the 3C339 cards, you
+  should use the tms380 driver instead.
+
+  If you have such an adapter, say Y and read the Token-Ring
+  mini-HOWTO, available from <http://www.linuxdoc.org/docs.html#howto>.
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will will be called 3c359.o. If you want to compile it
+  as a module, say M here and read Documentation/modules.txt.
+
+  Also read the file <file:Documentation/networking/3c359.txt> or check the 
+  Linux Token Ring Project site for the latest information at
+  <http://www.linuxtr.net>
+
 Sun Happy Meal 10/100baseT support
 CONFIG_HAPPYMEAL
   This driver supports the "hme" interface present on most Ultra
@@ -12661,18 +12930,6 @@
   of debug messages to the system log. Select this if you are having a
   problem with USB support and want to see more of what is going on.
 
-USB fetch large config
-CONFIG_USB_LARGE_CONFIG
-  This option changes the initial request for a config descriptor so
-  that some poorly designed devices will still work.  Some APC UPSes
-  need it.  Basically, the usb subsystem sends a request for a short
-  (8 byte) config, just to find out how large the real config is.
-  Incorrectly implemented devices may choke on this small config
-  request.  This option make the initial request for a quite large
-  config (1009 bytes), and things just work.
-
-  If you have an APC UPS, say Y; otherwise say N.
-
 USB long timeout for slow-responding devices (some MGE Ellipse UPSes)
 CONFIG_USB_LONG_TIMEOUT
   This option makes the standard time out a bit longer.  Basically,
@@ -12683,6 +12940,30 @@
   If you have an MGE Ellipse UPS, or you see timeouts in HID
   transactions, say Y; otherwise say N.
 
+EHCI (USB 2.0) support
+CONFIG_USB_EHCI_HCD
+  The Enhanced Host Controller Interface (EHCI) is standard for USB 2.0
+  "high speed" (480 Mbit/sec, 60 Mbyte/sec) host controller hardware.
+  If your USB host controller supports USB 2.0, you will likely want to
+  configure this Host Controller Driver.  At this writing, the primary
+  implementation of EHCI is a chip from NEC, widely available in add-on
+  PCI cards, but implementations are in the works from other vendors
+  including Intel and Philips.  Motherboard support is appearing.
+
+  EHCI controllers are packaged with "companion" host controllers (OHCI
+  or UHCI) to handle USB 1.1 devices connected to root hub ports.  Ports
+  will connect to EHCI if it the device is high speed, otherwise they
+  connect to a companion controller.  If you configure EHCI, you should
+  probably configure the OHCI (for NEC and some other vendors) USB Host
+  Controller Driver too.
+
+  You may want to read <file:Documentation/usb/ehci.txt>.
+
+  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 ehci-hcd.o. If you want to compile it as a
+  module, say M here and read <file:Documentation/modules.txt>.
+
 UHCI (Intel PIIX4, VIA, ...) support
 CONFIG_USB_UHCI
   The Universal Host Controller Interface is a standard by Intel for
@@ -12744,9 +13025,13 @@
 CONFIG_USB_HID
   Say Y here if you want full HID support to connect keyboards,
   mice, joysticks, graphic tablets, or any other HID based devices
-  to your computer via USB. You can't use this driver and the
-  HIDBP (Boot Protocol) keyboard and mouse drivers at the same time.
-  More information is available: <file:Documentation/input/input.txt>.
+  to your computer via USB. You also need to select HID Input layer
+  support (below) if you want to use keyboards, mice, joysticks and
+  the like.
+
+  You can't use this driver and the HIDBP (Boot Protocol) keyboard
+  and mouse drivers at the same time. More information is available:
+  <file:Documentation/input/input.txt>.
 
   If unsure, say Y.
 
@@ -12755,6 +13040,14 @@
   The module will be called hid.o. If you want to compile it as a
   module, say M here and read <file:Documentation/modules.txt>.
 
+USB HID Input layer support
+CONFIG_USB_HIDINPUT
+  Say Y here if you want to use a USB keyboard, mouse or joystick,
+  or any other HID input device. You also need Input layer support, 
+  (CONFIG_INPUT) which you select under "Input core support".
+
+  If unsure, say Y.
+
 /dev/usb/hiddev raw HID device support
 CONFIG_USB_HIDDEV
   Say Y here if you want to support HID devices (from the USB
@@ -12765,33 +13058,37 @@
   event interface on /dev/usb/hiddevX (char 180:96 to 180:111).
   This driver requires CONFIG_USB_HID.
 
-  If unsure, say N.
+  If unsure, say Y.
 
 USB HIDBP Keyboard (basic) support
 CONFIG_USB_KBD
-  Say Y here if you don't want to use the generic HID driver for your
-  USB keyboard and prefer to use the keyboard in its limited Boot
-  Protocol mode instead. This driver is much smaller than the HID one.
+  Say Y here only if you are absolutely sure that you don't want
+  to use the generic HID driver for your USB keyboard and prefer
+  to use the keyboard in its limited Boot Protocol mode instead.
+
+  This is almost certainly not what you want.
 
   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 usbkbd.o. If you want to compile it as a
   module, say M here and read <file:Documentation/modules.txt>.
 
-  If unsure, say N.
+  If even remotely unsure, say N.
 
 USB HIDBP Mouse (basic) support
 CONFIG_USB_MOUSE
-  Say Y here if you don't want to use the generic HID driver for your
-  USB mouse and prefer to use the mouse in its limited Boot Protocol
-  mode instead. This driver is much smaller than the HID one.
+  Say Y here only if you are absolutely sure that you don't want
+  to use the generic HID driver for your USB keyboard and prefer
+  to use the keyboard in its limited Boot Protocol mode instead.
+
+  This is almost certainly not what you want.
 
   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 usbmouse.o. If you want to compile it as
   a module, say M here and read <file:Documentation/modules.txt>.
 
-  If unsure, say N.
+  If even remotely unsure, say N.
 
 Wacom Intuos/Graphire tablet support
 CONFIG_USB_WACOM
@@ -12927,6 +13224,20 @@
   The module will be called audio.o. If you want to compile it as a
   module, say M here and read <file:Documentation/modules.txt>.
 
+EMI 2|6 USB Audio interface support
+CONFIG_USB_EMI26
+  This driver loads firmware to Emagic EMI 2|6 low latency USB
+  Audio interface.
+
+  After firmware load the device is handled with standard linux
+  USB Audio driver.
+
+  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 audio.o. If you want to compile it as a
+  module, say M here and read <file:Documentation/modules.txt>.
+			
+
 USB Modem (CDC ACM) support
 CONFIG_USB_ACM
   This driver supports USB modems and ISDN adapters which support the
@@ -12985,9 +13296,10 @@
 
 USB Compaq iPAQ Driver
 CONFIG_USB_SERIAL_IPAQ
-  Say Y here if you want to connect to your Compaq iPAQ running
-  Windows CE 3.0 using a USB autosync cable. For information on using
-  the driver, read <file:Documentation/usb/usb-serial.txt>.
+  Say Y here if you want to connect to your Compaq iPAQ, HP Jornada 548/568
+  or Casio EM500 running Windows CE 3.0 or PocketPC 2002 using a USB
+  cradle/cable. For information on using the driver,
+  read <file:Documentation/usb/usb-serial.txt>.
 
   This code is also available as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want).
@@ -13282,6 +13594,7 @@
         * Motorola (DM100 and SB4100)
         * Broadcom Cable Modem (reference design)
         * Toshiba PCX1100U and possibly other cable modems
+        * Sharp Zaurus SL-5000D
 
   The device creates a network device (ethX, where X depends on what
   other networking devices you have in use), as for a normal PCI
@@ -13375,18 +13688,29 @@
 
 Pegasus/Pegasus II based USB-Ethernet device support
 CONFIG_USB_PEGASUS
-  Say Y here if you know you have Pegasus or Pegasus II based adapter.
+  Say Y here if you know you have Pegasus or Pegasus-II based adapter.
   If in doubt then look at linux/drivers/usb/pegasus.h for the complete
   list of supported devices.
   If your particular adapter is not in the list and you are _sure_ it
-  is Pegasus or Pegasus II based then send me (pmanolov@lnxw.com) vendor
-  and device IDs.
-
+  is Pegasus or Pegasus-II based then send me (pmanolov@users.sourceforge.net)
+  vendor and device IDs.
+  
   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 pegasus.o. If you want to compile it as a
   module, say M here and read <file:Documentation/modules.txt>.
 
+Realtek RTL8150 based USB-Ethernet device support
+CONFIG_USB_RTL8150
+  Say Y here if you have RTL8150 based usb-ethernet adapter.
+  Send me (petkan@users.sourceforge.net) any comments you may have.
+  You can also check for updates at http://pegasus2.sourceforge.net/
+
+  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 rtl8150.o. If you want to compile it as a
+  module, say M here and read <file:Documentation/modules.txt>.
+
 USB KLSI KL5USB101-based Ethernet device support
 CONFIG_USB_KAWETH
   Say Y here if you want to use one of the following 10Mbps only
@@ -13621,6 +13945,27 @@
   The module will be called rio500.o. If you want to compile it as
   a module, say M here and read <file:Documentation/modules.txt>.
 
+USB Auerswald ISDN device support
+CONFIG_USB_AUERSWALD
+  Say Y here if you want to connect an Auerswald USB ISDN Device
+  to your computer's USB port.
+
+  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 auerswald.o. If you want to compile it as
+  a module, say M here and read <file:Documentation/modules.txt>.
+
+Tieman Voyager USB Braille display support
+CONFIG_USB_BRLVOYAGER
+  Say Y here if you want to use the Voyager USB Braille display from
+  Tieman. See <file:Documentation/usb/brlvger.txt> for more
+  information.
+
+  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 brlvger.o. If you want to compile it as
+  a module, say M here and read <file:Documentation/modules.txt>.
+
 D-Link DSB-R100 FM radio support
 CONFIG_USB_DSBR
   Say Y here if you want to connect this type of radio to your
@@ -14402,9 +14747,16 @@
   other useful pieces of information.  Sometimes this information is
   not present or incorrect.
 
-  Unless you expect to boot on a PReP system, there is not need to
+  Unless you expect to boot on a PReP system, there is no need to
   select Y.
 
+PReP residual data available in /proc/residual
+CONFIG_PROC_PREPRESIDUAL
+  Enabling this option will create a /proc/residual file which allows
+  you to get at the residual data on PReP systems.  You will need a tool
+  (lsresidual) to parse it.  If you aren't on a PReP system, you don't
+  want this.
+
 /dev file system support
 CONFIG_DEVFS_FS
   This is support for devfs, a virtual file system (like /proc) which
@@ -14674,10 +15026,12 @@
 
 QNX4 file system support (read only)
 CONFIG_QNX4FS_FS
-  This is the file system used by the operating system QNX 4. Say Y if
-  you intend to mount QNX hard disks or floppies. Unless you say Y to
-  "QNX4FS read-write support" below, you will only be able to read
-  these file systems.
+  This is the file system used by the real-time operating systems
+  QNX 4 and QNX 6 (the latter is also called QNX RTP).
+  Further information is available at <http://www.qnx.com/>.
+  Say Y if you intend to mount QNX hard disks or floppies.
+  Unless you say Y to "QNX4FS read-write support" below, you will
+  only be able to read these file systems.
 
   This file system support is also available as a module ( = code
   which can be inserted in and removed from the running kernel
@@ -14692,6 +15046,9 @@
 CONFIG_QNX4FS_RW
   Say Y if you want to test write support for QNX4 file systems.
 
+  It's currently broken, so for now:
+  answer N.
+
 Kernel automounter support
 CONFIG_AUTOFS_FS
   The automounter is a tool to automatically mount remote file systems
@@ -16394,6 +16751,13 @@
   If you have a Cobalt Networks system, you should say Y here,
   unless you are absolutely sure.
 
+IT8172G Sound
+CONFIG_SOUND_IT8172
+  Say Y here to support the on-board sound generator on the Integrated
+  Technology Express, Inc. ITE8172 SBC.  Vendor page at
+  <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the
+  board at <http://www.mvista.com/allies/semiconductor/ite.html>.
+
 I2C support
 CONFIG_I2C
   I2C (pronounce: I-square-C) is a slow serial bus protocol used in
@@ -16492,6 +16856,28 @@
   <file:Documentation/modules.txt>.
   The module will be called i2c-elektor.o.
 
+ITE I2C Algorithm
+CONFIG_ITE_I2C_ALGO
+  This supports the use the ITE8172 I2C interface found on some MIPS
+  systems. Say Y if you have one of these. You should also say Y for
+  the ITE I2C peripheral driver support below.
+
+  This support is also available as a module. If you want to compile
+  it as a modules, say M here and read
+  <file:Documentation/modules.txt>.
+  The module will be called i2c-algo-ite.o.
+
+ITE I2C Adapter
+CONFIG_ITE_I2C_ADAP
+  This supports the ITE8172 I2C peripheral found on some MIPS
+  systems. Say Y if you have one of these. You should also say Y for
+  the ITE I2C driver algorithm support above.
+
+  This support is also available as a module. If you want to compile
+  it as a module, say M here and read
+  <file:Documentation/modules.txt>.
+  The module will be called i2c-adap-ite.o.
+
 I2C device interface
 CONFIG_I2C_CHARDEV
   Say Y here to use i2c-* device files, usually found in the /dev
@@ -17551,6 +17937,17 @@
   module, say M here and read <file:Documentation/modules.txt>.  Most
   people will say N.
 
+ALi M7101 Watchdog Timer
+CONFIG_ALIM7101_WDT
+  This is the driver for the hardware watchdog on the ALi M7101 PMU
+  as used in the x86 Cobalt servers.
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module is called alim7101_wdt.o.  If you want to compile it as a
+  module, say M here and read <file:Documentation/modules.txt>.  Most
+  people will say N.
+
 IB700 SBC Watchdog Timer
 CONFIG_IB700_WDT
   This is the driver for the hardware watchdog on the IB700 Single
@@ -17592,6 +17989,18 @@
   The module is called machzwd.o.  If you want to compile it as a
   module, say M here and read <file:Documentation/modules.txt>.
 
+CONFIG_SC1200_WDT
+  This is a driver for National Semiconductor PC87307/PC97307 hardware
+  watchdog cards as found on the SC1200. This watchdog is mainly used
+  for power management purposes and can be used to power down the device
+  during inactivity periods (includes interrupt activity monitoring).
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module is called sc1200wdt.o.  If you want to compile it as a
+  module, say M here and read <file:Documentation/modules.txt>.  Most
+  people will say N.
+
 SuperH 3/4 Watchdog
 CONFIG_SH_WDT
   This driver adds watchdog support for the integrated watchdog in the
@@ -17602,7 +18011,29 @@
   inserted in and removed from the running kernel whenever you want).
   The module is called shwdt.o. If you want to compile it as a module,
   say M here and read Documentation/modules.txt.
+
+Wafer 5823 Watchdog
+CONFIG_WAFER_WDT
+  This is a driver for the hardware watchdog on the ICP Wafer 5823
+  Single Board Computer (and probably other similar models).
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  <file:Documentation/modules.txt>. The module will be called
+  wafer5823wdt.o
 	      
+Machine Check Exception
+CONFIG_X86_MCE
+  Machine Check Exception support allows the processor to notify the
+  kernel if it detects a problem (e.g. overheating, component failure).
+  The action the kernel takes depends on the severity of the problem, 
+  ranging from a warning message on the console, to halting the machine.
+  You can safely select this on machines that do not support this feature.
+
+  For pentium machines the mce support defaults to off as the mainboard
+  support is not always present. You must activate it as a boot option.
+
 Toshiba Laptop support
 CONFIG_TOSHIBA
   This adds a driver to safely access the System Management Mode of
@@ -17690,6 +18121,28 @@
   CPU-1410 cards.  These are PC/104 SBCs. Spec sheets and product 
   information are at <http://www.eurotech.it/>.
 
+W83877F Watchdog Timer
+CONFIG_W83877F_WDT
+ This is the driver for the hardware watchdog on the W83877F chipset
+ as used in EMACS PC-104 motherboards (and may work on others). This
+ watchdog simply watches your kernel to make sure it doesn't freeze,
+ and if it does, it reboots your computer after a certain amount of
+ time.
+
+ You can compile this driver directly into the kernel, or use
+ it as a module.  The module will be called w83877f_wdt.o.
+
+SC520 (AMD Elan) Watchdog Timer
+CONFIG_SC520_WDT
+ This is the driver for the hardware watchdog built in to the
+ AMD "Elan" SC520 microcomputer commonly used in embedded systems.
+ This watchdog simply watches your kernel to make sure it doesn't
+ freeze, and if it does, it reboots your computer after a certain
+ amount of time.
+
+ You can compile this driver directly into the kernel, or use
+ it as a module.  The module will be called sc520_wdt.o.
+
 Enhanced Real Time Clock Support
 CONFIG_RTC
   If you say Y here and create a character special file /dev/rtc with
@@ -18184,7 +18637,7 @@
   then you can get the persistent DMA buffer functionality by passing
   the command-line argument "dmabuf=1" to the sound.o module.
 
-  Say Y unless you have 16MB or more RAM or a PCI sound card.
+  Say Y unless you have 16MB or less RAM or a PCI sound card.
 
 Support for Aztech Sound Galaxy (non-PnP) cards
 CONFIG_SOUND_SGALAXY
@@ -18360,6 +18813,12 @@
   <file:Documentation/sound/vwsnd> for more info on this driver's
   capabilities.
 
+NEC Vrc5477 AC97 sound
+CONFIG_SOUND_VRC5477
+  Say Y here to enable sound support for the NEC Vrc5477 chip, an
+  integrated, multi-function controller chip for MIPS CPUs.  Works
+  with the AC97 codec.
+
 Ensoniq SoundScape support
 CONFIG_SOUND_SSCAPE
   Answer Y if you have a sound card based on the Ensoniq SoundScape
@@ -18707,6 +19166,12 @@
   driver as a module you have to specify the MPU I/O base address with
   the parameter 'mpu_base=0xNNN'.
 
+SC-6600 CDROM Interface (4=None, 3=IDE, 1=Panasonic, 0=?Sony?)
+CONFIG_SC6600_CDROM
+  This is used to activate the CD-ROM interface of the Audio Excel
+  DSP 16 card. Enter: 0 for Sony, 1 for Panasonic, 2 for IDE, 4 for no
+  CD-ROM present.
+
 C-Media PCI (CMI8338/8378)
 CONFIG_SOUND_CMPCI
   Say Y or M if you have a PCI sound card using the CMI8338
@@ -18750,20 +19215,57 @@
   This package will among other things help you enable SPDIF 
   out/in/loop/monitor.
 
+Enable legacy FM
+CONFIG_SOUND_CMPCI_FM
+  Say Y here to enable the legacy FM (frequency-modulation) synthesis
+  support on a card using the CMI8338 or CMI8378 chipset.
+
+FM I/O 388, 3C8, 3E0, 3E8
+CONFIG_SOUND_CMPCI_FMIO
+  Set the base I/O address for FM synthesis control on a card using
+  the CMI8338 or CMI8378 chipset.
+
+Enable legacy MPU-401
+CONFIG_SOUND_CMPCI_MIDI
+  Say Y here to enable the legacy MP401 MIDI synthesis support on a
+  card using the CMI8338 or CMI8378 chipset.
+
+MPU-401 I/O 330, 320, 310, 300
+CONFIG_SOUND_CMPCI_MPUIO
+  Set the base I/O address for MP401 MIDI synthesis control on a card
+  using the CMI8338 or CMI8378 chipset.
+
+Inverse S/PDIF in for CMI8738
+CONFIG_SOUND_CMPCI_SPDIFINVERSE
+  Say Y here to have the driver invert the signal presented on SPDIF IN
+  of a card using the CMI8338 or CMI8378 chipset.
+
+Use Line-in as Read-out
+CONFIG_SOUND_CMPCI_LINE_REAR
+  Say Y here to enable using line-in jack as an output jack for a rear
+  speaker.
+
+Use Line-in as Bass
+CONFIG_SOUND_CMPCI_LINE_BASS
+  Say Y here to enable using line-in jack as an output jack for a bass
+  speaker.
+
 Creative SBLive! (EMU10K1) based PCI sound cards
 CONFIG_SOUND_EMU10K1
   Say Y or M if you have a PCI sound card using the EMU10K1 chipset,
   such as the Creative SBLive!, SB PCI512 or Emu-APS.
 
-  For more information on this driver and the degree of support for the
-  different card models please check <http://opensource.creative.com/>.
+  For more information on this driver and the degree of support for
+  the different card models please check:
+
+	<http://sourceforge.net/projects/emu10k1/>
 
   It is now possible to load dsp microcode patches into the EMU10K1
   chip.  These patches are used to implement real time sound
   processing effects which include for example: signal routing,
   bass/treble control, AC3 passthrough, ...
   Userspace tools to create new patches and load/unload them can be
-  found at <http://opensource.creative.com/dist.html>.
+  found in the emu-tools package at the above URL.
 
 Creative SBLive! (EMU10K1) MIDI
 CONFIG_MIDI_EMU10K1
@@ -18943,8 +19445,11 @@
 
 Yamaha YMF7xx PCI audio (native mode)
 CONFIG_SOUND_YMFPCI
-  Support for Yamaha cards including the YMF711, YMF715, YMF718,
-  YMF719, YMF724, Waveforce 192XG, and Waveforce 192 Digital.
+  Support for Yamaha cards with the following chipsets: YMF724,
+  YMF724F, YMF740, YMF740C, YMF744, and YMF754.
+
+  Two common cards that use this type of chip are Waveforce 192XG,
+  and Waveforce 192 Digital.
 
 Yamaha PCI legacy ports support
 CONFIG_SOUND_YMFPCI_LEGACY
@@ -18952,8 +19457,9 @@
 
 RME Hammerfall (RME96XX) support
 CONFIG_SOUND_RME96XX
-  Say Y or M if you have a Hammerfall, Hammerfall light or Hammerfall
-  DSP card from RME.
+  Say Y or M if you have a Hammerfall or Hammerfall light multichannel card 
+  from RME. If you want to acess advanced features of the card, read
+  Documentation/sound/rme96xx.
 
 Are you using a crosscompiler
 CONFIG_CROSSCOMPILE
@@ -19504,6 +20010,10 @@
   This enables the PCMCIA client driver for the Sedlbauer Speed Star
   and Speed Star II cards.
 
+CONFIG_HISAX_AVM_A1_CS
+  This enables the PCMCIA client driver for the AVM A1 / Fritz!Card
+  PCMCIA cards.
+
 ST5481 USB ISDN modem
 CONFIG_HISAX_ST5481
   This enables the driver for ST5481 based USB ISDN adapters,
@@ -19854,6 +20364,11 @@
   found on many Sun machines. Note that many of the newer Ultras
   actually have pc style hardware instead.
 
+SPARC power management support
+CONFIG_SUN_PM
+  Enable power management and CPU standby features on supported 
+  SPARC platforms. 
+
 /proc/hardware support
 CONFIG_PROC_HARDWARE
   Say Y here to support the /proc/hardware file, which gives you
@@ -19870,11 +20385,12 @@
   Bluetooth can be found at <http://www.bluetooth.com/>.
 
   Linux Bluetooth subsystem consist of several layers:
-               HCI Core (device and connection manager, scheduler)
+               BlueZ Core (HCI device and connection manager, scheduler)
                HCI Device drivers (interface to the hardware)
                L2CAP Module (L2CAP protocol)
+               SCO Module (SCO links)
 
-  Say Y here to enable Linux Bluetooth support and to build HCI Core
+  Say Y here to enable Linux Bluetooth support and to build BlueZ Core
   layer.
 
   To use Linux Bluetooth subsystem, you will need several user-space
@@ -19882,7 +20398,7 @@
   Bluetooth kernel modules are provided in the BlueZ package.
   For more information, see <http://bluez.sourceforge.net/>.
 
-  If you want to compile HCI Core as module (hci.o) say M here.
+  If you want to compile BlueZ Core as module (bluez.o) say M here.
 
 L2CAP protocol support
 CONFIG_BLUEZ_L2CAP
@@ -19893,15 +20409,33 @@
   Say Y here to compile L2CAP support into the kernel or say M to
   compile it as module (l2cap.o).
 
+SCO links support
+CONFIG_BLUEZ_SCO
+  SCO link provides voice transport over Bluetooth. SCO support is
+  required for voice applications like Headset and Audio.
+
+  Say Y here to compile SCO support into the kernel or say M to
+  compile it as module (sco.o).
+
 HCI UART driver
 CONFIG_BLUEZ_HCIUART
   Bluetooth HCI UART driver.
   This driver is required if you want to use Bluetooth devices with
-  serial port interface.
+  serial port interface. You will also need this driver if you have 
+  UART based Bluetooth PCMCIA and CF devices like Xircom Credit Card 
+  adapter and BrainBoxes Bluetooth PC Card.
 
   Say Y here to compile support for Bluetooth UART devices into the
   kernel or say M to compile it as module (hci_uart.o).
 
+HCI UART (H4) protocol support 
+CONFIG_BLUEZ_HCIUART_H4
+  UART (H4) is serial protocol for communication between Bluetooth 
+  device and host. This protocol is required for most UART based 
+  Bluetooth device (including PCMCIA and CF). 
+
+  Say Y here to compile support for HCI UART (H4) protocol.
+
 HCI USB driver
 CONFIG_BLUEZ_HCIUSB
   Bluetooth HCI USB driver.
@@ -19911,7 +20445,24 @@
   Say Y here to compile support for Bluetooth USB devices into the
   kernel or say M to compile it as module (hci_usb.o).
 
-HCI VHCI virtual HCI device driver
+HCI USB firmware download support
+CONFIG_BLUEZ_USB_FW_LOAD
+  Firmware download support for Bluetooth USB devices.
+  This support is required for devices like Broadcom BCM2033.
+
+  HCI USB driver uses external firmware downloader program provided 
+  in BlueFW package.
+  For more information, see <http://bluez.sf.net/>.
+
+HCI USB zero packet support
+CONFIG_BLUEZ_USB_ZERO_PACKET
+  Support for USB zero packets. 
+  This option is provided only as a work around for buggy Bluetooth USB 
+  devices. Do _not_ enable it unless you know for sure that your device 
+  requires zero packets.
+  Most people should say N here.
+
+HCI VHCI Virtual HCI device driver
 CONFIG_BLUEZ_HCIVHCI
   Bluetooth Virtual HCI device driver.
   This driver is required if you want to use HCI Emulation software.
@@ -19919,6 +20470,16 @@
   Say Y here to compile support for virtual HCI devices into the
   kernel or say M to compile it as module (hci_vhci.o).
 
+HCI DTL1 (PC Card) device driver
+CONFIG_BLUEZ_HCIDTL1
+  Bluetooth HCI DTL1 (PC Card) driver.
+  This driver provides support for Bluetooth PCMCIA devices with
+  Nokia DTL1 interface:
+     Nokia Bluetooth PC Card, Socketcom Bluetooth CF module
+
+  Say Y here to compile support for HCI DTL1 devices into the
+  kernel or say M to compile it as module (dtl1_cs.o).
+
 # The following options are for Linux when running on the Hitachi
 # SuperH family of RISC microprocessors.
 
@@ -20027,9 +20588,13 @@
 Sun 3 support
 CONFIG_SUN3
   This option enables support for the Sun 3 series of workstations.
-  Currently, only the Sun 3/80 is supported within the Sun 3x family.
-  You will also want to enable 68030 support.  General Linux
-  information on the Sun 3x series (now discontinued) is at
+  Note that if this option is enabled, support for all other m68k 
+  platforms above must be disabled in order to produce a working 
+  kernel.
+
+  Also, you will want to enable 68020 support below, and disable 
+  all other CPU types.  General Linux information on the Sun 3x series
+  (now discontinued) is at
   <http://www.angelfire.com/ca2/tech68k/sun3.html>.
 
   If you don't want to compile a kernel for a Sun 3, say N.
@@ -20037,8 +20602,8 @@
 Sun 3X support
 CONFIG_SUN3X
   This option enables support for the Sun 3x series of workstations.
-  Be warned that this support is very experimental. You will also want
-  to say Y to 68020 support and N to the other processors below.
+  Currently, only the Sun 3/80 is supported within the Sun 3x family.
+  You will also want to enable 68030 support below  
   General Linux information on the Sun 3x series (now discontinued)
   is at <http://www.angelfire.com/ca2/tech68k/sun3.html>.
 
@@ -20049,8 +20614,7 @@
   ZS refers to a type of asynchronous serial port built in to the Sun3
   and Sun3x workstations; if you have a Sun 3, you probably have
   these.  Say 'Y' to support ZS ports directly.  This option must be
-  enabled in order to support the
-  keyboard and mouse ports.
+  enabled in order to support the keyboard and mouse ports.
 
 Sun keyboard support
 CONFIG_SUN_KEYBOARD
@@ -20348,6 +20912,17 @@
   Hades. This increases the SCSI transfer rates at least ten times
   compared to PIO transfers.
 
+Sun3 NCR5380 OBIO SCSI
+CONFIG_SUN3_SCSI
+  This option will enable support for the OBIO (onboard io) NCR5380
+  SCSI controller found in the Sun 3/50 and 3/60.  Note that this
+  driver does not provide support for VME SCSI boards.
+
+Sun3x ESP SCSI
+CONFIG_SUN3X_ESP
+  This option will enable support for the ESP SCSI controller found
+  onboard the Sun 3/80.
+
 Ariadne support
 CONFIG_ARIADNE
   If you have a Village Tronic Ariadne Ethernet adapter, say Y.
@@ -20411,6 +20986,19 @@
   want). The module is called apne.o. If you want to compile it as a
   module, say M here and read <file:Documentation/modules.txt>.
 
+Sun3/Sun3x on-board LANCE support
+CONFIG_SUN3LANCE
+  This driver enables support for the on-board LANCE ethernet adapter
+  found on the Sun 3/50, 3/60, and 3/80 workstations.  If you have 
+  one of these workstations, and would like Ethernet, say Y. 
+  Otherwise, say N.
+
+Sun3 on-board Intel 82586 support
+CONFIG_SUN3_82586
+  This driver enables support for the on-board Intel 82586 based Ethernet
+  adapter found on Sun 3/1xx and 3/2xx motherboards.  Note that this driver
+  does not support 82586-based adapters on additional VME boards.
+
 Atari Lance support
 CONFIG_ATARILANCE
   Say Y to include support for several Atari Ethernet adapters based
@@ -21662,6 +22250,18 @@
   Say Y here to include support for the Iomega Buz video card.  There
   is a Buz/Linux homepage at <http://www.lysator.liu.se/~gz/buz/>.
 
+Miro DC10(+) support
+CONFIG_VIDEO_ZORAN_DC10
+  Say Y to support the Pinnacle Systems Studio DC10 plus TV/Video
+  card.  Linux page at
+  <http://lhd.datapower.com/db/dispproduct.php3?DISP?1511>.  Vendor
+  page at <http://www.pinnaclesys.com/>.
+
+Linux Media Labs LML33 support
+CONFIG_VIDEO_ZORAN_LML33
+  Say Y here to support the Linux Media Labs LML33 TV/Video card.
+  Resources page is at <http://www.linuxmedialabs.com/lml33doc.html>.
+
 Zoran ZR36120/36125 Video For Linux
 CONFIG_VIDEO_ZR36120
   Support for ZR36120/ZR36125 based frame grabber/overlay boards.
@@ -22409,12 +23009,12 @@
   you are concerned with the code size or don't want to see these
   messages.
 
-Compile kernel without frame pointer
-CONFIG_NO_FRAME_POINTER
-  If you say Y here, the resulting kernel will be slightly smaller and
-  faster. However, when a problem occurs with the kernel, the
-  information that is reported is severely limited. Most people
-  should say N here.
+Compile kernel with frame pointer
+CONFIG_FRAME_POINTER
+  If you say Y here, the resulting kernel will be slightly larger and
+  slower, but it will give very useful debugging information. If you
+  don't debug the kernel, you can say N, but we may not be able to
+  solve problems without frame pointers.
 
 Verbose user fault messages
 CONFIG_DEBUG_USER
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/DocBook/Makefile linux/Documentation/DocBook/Makefile
--- linux.orig/Documentation/DocBook/Makefile	Sat Nov  3 01:13:53 2001
+++ linux/Documentation/DocBook/Makefile	Tue May 28 22:39:27 2002
@@ -23,6 +23,8 @@
 
 html:	$(HTML)
 
+man:	kernel-api-man
+
 %.eps: %.fig
 	fig2dev -Leps $< $@
 
@@ -93,6 +95,8 @@
 		$(TOPDIR)/drivers/net/8390.c \
 		$(TOPDIR)/drivers/char/serial.c \
 		$(TOPDIR)/drivers/pci/pci.c \
+		$(TOPDIR)/drivers/hotplug/pci_hotplug_core.c \
+		$(TOPDIR)/drivers/hotplug/pci_hotplug_util.c \
 		$(TOPDIR)/drivers/block/ll_rw_blk.c \
 		$(TOPDIR)/drivers/sound/sound_core.c \
 		$(TOPDIR)/drivers/sound/sound_firmware.c \
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/DocBook/kernel-api.tmpl linux/Documentation/DocBook/kernel-api.tmpl
--- linux.orig/Documentation/DocBook/kernel-api.tmpl	Fri Oct  5 19:06:51 2001
+++ linux/Documentation/DocBook/kernel-api.tmpl	Tue May 28 22:39:12 2002
@@ -162,6 +162,10 @@
      <sect1><title>PCI Support Library</title>
 !Edrivers/pci/pci.c
      </sect1>
+     <sect1><title>PCI Hotplug Support Library</title>
+!Edrivers/hotplug/pci_hotplug_core.c
+!Edrivers/hotplug/pci_hotplug_util.c
+     </sect1>
      <sect1><title>MCA Architecture</title>
 	<sect2><title>MCA Device Functions</title>
 !Earch/i386/kernel/mca.c
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/DocBook/kernel-hacking.tmpl linux/Documentation/DocBook/kernel-hacking.tmpl
--- linux.orig/Documentation/DocBook/kernel-hacking.tmpl	Mon Feb 25 19:37:51 2002
+++ linux/Documentation/DocBook/kernel-hacking.tmpl	Tue May 28 22:39:29 2002
@@ -1026,7 +1026,7 @@
     Similar to <function>EXPORT_SYMBOL()</function> except that the
     symbols exported by <function>EXPORT_SYMBOL_GPL()</function> can
     only be seen by modules with a
-    <function>MODULE_LICENCE()</function> that specifies a GPL
+    <function>MODULE_LICENSE()</function> that specifies a GPL
     compatible license.
    </para>
   </sect1>
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/DocBook/kernel-locking.tmpl linux/Documentation/DocBook/kernel-locking.tmpl
--- linux.orig/Documentation/DocBook/kernel-locking.tmpl	Sun May 20 00:43:05 2001
+++ linux/Documentation/DocBook/kernel-locking.tmpl	Tue May 28 22:39:23 2002
@@ -788,8 +788,18 @@
     </para>
 
     <para>
-      Note that the atomic operations are defined to act as both
-      read and write barriers on all platforms.
+      Note that the atomic operations do in general not act as memory
+      barriers. Instead you can insert a memory barrier before or
+      after <function>atomic_inc()</function> or
+      <function>atomic_dec()</function> by inserting
+      <function>smp_mb__before_atomic_inc()</function>,
+      <function>smp_mb__after_atomic_inc()</function>,
+      <function>smp_mb__before_atomic_dec()</function> or
+      <function>smp_mb__after_atomic_dec()</function>
+      respectively. The advantage of using those macros instead of
+      <function>smp_mb()</function> is, that they are cheaper on some
+      platforms.    
+      <!-- Sebastian Wilhelmi <seppi@seppi.de> 2002-03-04 -->
     </para>
    </sect1>
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/IRQ-affinity.txt linux/Documentation/IRQ-affinity.txt
--- linux.orig/Documentation/IRQ-affinity.txt	Fri Feb 25 06:41:16 2000
+++ linux/Documentation/IRQ-affinity.txt	Tue May 28 22:39:12 2002
@@ -8,7 +8,7 @@
 affinity then the value will not change from the default 0xffffffff.
 
 Here is an example of restricting IRQ44 (eth1) to CPU0-3 then restricting
-the IRQ to CPU4-8 (this is an 8-CPU SMP box):
+the IRQ to CPU4-7 (this is an 8-CPU SMP box):
 
 [root@moon 44]# cat smp_affinity
 ffffffff
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/SubmittingDrivers linux/Documentation/SubmittingDrivers
--- linux.orig/Documentation/SubmittingDrivers	Mon Aug 27 15:59:16 2001
+++ linux/Documentation/SubmittingDrivers	Tue May 28 22:39:18 2002
@@ -3,7 +3,7 @@
 
 This document is intended to explain how to submit device drivers to the
 Linux 2.2 and 2.4 kernel trees. Note that if you are interested in video
-card drivers you should probably talk to XFree86 (http://wwww.xfree86.org) 
+card drivers you should probably talk to XFree86 (http://www.xfree86.org) 
 instead.
 
 Also read the Documentation/SubmittingPatches document.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/cachetlb.txt linux/Documentation/cachetlb.txt
--- linux.orig/Documentation/cachetlb.txt	Fri Dec 21 17:41:53 2001
+++ linux/Documentation/cachetlb.txt	Tue May 28 22:39:23 2002
@@ -339,7 +339,18 @@
 	If the icache does not snoop stores then this routine will need
 	to flush it.
 
+  void flush_icache_user_range(struct vm_area_struct *vma,
+			struct page *page, unsigned long addr, int len)
+	This is called when the kernel stores into addresses that are
+	part of the address space of a user process (which may be some
+	other process than the current process).  The addr argument
+	gives the virtual address in that process's address space,
+	page is the page which is being modified, and len indicates
+	how many bytes have been modified.  The modified region must
+	not cross a page boundary.  Currently this is only called from
+	kernel/ptrace.c.
+
   void flush_icache_page(struct vm_area_struct *vma, struct page *page)
-	All the functionality of flush_icache_page can be implemented in
-	flush_dcache_page and update_mmu_cache. In 2.5 the hope is to
-	remove this interface completely.
+	This is called when a page-cache page is about to be mapped
+	into a user process' address space.  It offers an opportunity
+	for a port to ensure d-cache/i-cache coherency if necessary.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/cciss.txt linux/Documentation/cciss.txt
--- linux.orig/Documentation/cciss.txt	Thu Oct 11 16:04:57 2001
+++ linux/Documentation/cciss.txt	Tue May 28 22:39:17 2002
@@ -100,7 +100,7 @@
 can be informed of changes to the virtual SCSI bus which the driver 
 presents to it in the usual way. For example: 
 
-	echo add-single-device 3 2 1 0 > /proc/scsi/scsi
+	echo scsi add-single-device 3 2 1 0 > /proc/scsi/scsi
  
 to add a device on controller 3, bus 2, target 1, lun 0.   Note that
 the driver makes an effort to preserve the devices positions
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/fb/matroxfb.txt linux/Documentation/fb/matroxfb.txt
--- linux.orig/Documentation/fb/matroxfb.txt	Sun Sep 30 19:26:08 2001
+++ linux/Documentation/fb/matroxfb.txt	Tue May 28 22:39:20 2002
@@ -10,7 +10,7 @@
 
  * It provides a nice large console (128 cols + 48 lines with 1024x768)
    without using tiny, unreadable fonts.
- * You can run XF68_FBDev on top of /dev/fb0
+ * You can run XF{68,86}_FBDev or XFree86 fbdev driver on top of /dev/fb0
  * Most important: boot logo :-)
 
 Disadvantages:
@@ -27,9 +27,6 @@
 
 If you want, for example, enable a resolution of 1280x1024x24bpp you should
 pass to the kernel this command line: "video=matrox:vesa:0x1BB".
-Note that the same line, if 'appended' as a lilo parameter in lilo.conf will
-read "video=matrox:vesa:443" because lilo pass integer parameters as decimal
-numbers to the kernel.
 
 You should compile in both vgacon (to boot if you remove you Matrox from
 box) and matroxfb (for graphics mode). You should not compile-in vesafb
@@ -82,13 +79,16 @@
 X11
 ===
 
-XF68_FBDev should work just fine, but it is non-accelerated. On non-intel
+XF{68,86}_FBDev should work just fine, but it is non-accelerated. On non-intel
 architectures there are some glitches for 24bpp videomodes. 8, 16 and 32bpp
 works fine.
 
 Running another (accelerated) X-Server like XF86_SVGA works too. But (at least)
 XFree servers have big troubles in multihead configurations (even on first
-head, not even talking about second).
+head, not even talking about second). Running XFree86 4.x accelerated mga 
+driver is possible, but you must not enable DRI - if you do, resolution and
+color depth of your X desktop must match resolution and color depths of your
+virtual consoles, otherwise X will corrupt accelerator settings.
 
 
 SVGALib
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/fb/tridentfb.txt linux/Documentation/fb/tridentfb.txt
--- linux.orig/Documentation/fb/tridentfb.txt	Mon Feb 25 19:37:51 2002
+++ linux/Documentation/fb/tridentfb.txt	Tue May 28 22:39:16 2002
@@ -42,8 +42,14 @@
 bpp  - bits per pixel (8,16 or 32)
 mode - a mode name like 800x600 (as described in Documentation/fb/modedb.txt)
 
+Example:
+video=trident:memsize=2048,800x600
+
 Using insane values for the above parameters will probably result in driver
 misbehaviour so take care(for instance memsize=12345678 or memdiff=23784 or
 nativex=93)
 
-Contact: jani@astechnix.ro
+If you have trouble with the driver you could check http://sf.net/projects/tridentfb
+to see if there's a newer version available.
+
+Contact: jani@iv.ro
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/filesystems/Locking linux/Documentation/filesystems/Locking
--- linux.orig/Documentation/filesystems/Locking	Fri Dec 21 17:41:53 2001
+++ linux/Documentation/filesystems/Locking	Tue May 28 22:39:23 2002
@@ -156,7 +156,7 @@
 block_flushpage() instead.
 	->releasepage() is called when the kernel is about to try to drop the
 buffers from the page in preparation for freeing it.  It returns zero to
-indicate that the buffers are (or may be) freeable.  If ->flushpage is zero,
+indicate that the buffers are (or may be) freeable.  If ->releasepage is zero,
 the kernel assumes that the fs has no private interest in the buffers.
 
 	Note: currently almost all instances of address_space methods are
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/filesystems/cramfs.txt linux/Documentation/filesystems/cramfs.txt
--- linux.orig/Documentation/filesystems/cramfs.txt	Thu Jul 19 23:14:53 2001
+++ linux/Documentation/filesystems/cramfs.txt	Tue May 28 22:39:31 2002
@@ -10,7 +10,7 @@
 
 You can't write to a cramfs filesystem (making it compressible and
 compact also makes it _very_ hard to update on-the-fly), so you have to
-create the disk image with the "mkcramfs" utility in scripts/cramfs.
+create the disk image with the "mkcramfs" utility.
 
 
 Usage Notes
@@ -19,9 +19,7 @@
 File sizes are limited to less than 16MB.
 
 Maximum filesystem size is a little over 256MB.  (The last file on the
-filesystem is allowed to extend past 256MB.)  (Comments in mkcramfs.c
-suggest that ROM sizes may be limited to 64MB, though that's not a
-limitation in cramfs code.)
+filesystem is allowed to extend past 256MB.)
 
 Only the low 8 bits of gid are stored.  The current version of
 mkcramfs simply truncates to 8 bits, which is a potential security
@@ -48,18 +46,28 @@
 
 
 For /usr/share/magic
-------------------
+--------------------
 
-0	long	0x28cd3d45	Linux cramfs
->4	long	x		size %d
->8	long	x		flags 0x%x
->12	long	x		future 0x%x
+0	ulelong	0x28cd3d45	Linux cramfs offset 0
+>4	ulelong	x		size %d
+>8	ulelong	x		flags 0x%x
+>12	ulelong	x		future 0x%x
 >16	string	>\0		signature "%.16s"
->32	long	x		fsid.crc 0x%x
->36	long	x		fsid.edition %d
->40	long	x		fsid.blocks %d
->44	long	x		fsid.files %d
+>32	ulelong	x		fsid.crc 0x%x
+>36	ulelong	x		fsid.edition %d
+>40	ulelong	x		fsid.blocks %d
+>44	ulelong	x		fsid.files %d
 >48	string	>\0		name "%.16s"
+512	ulelong	0x28cd3d45	Linux cramfs offset 512
+>516	ulelong	x		size %d
+>520	ulelong	x		flags 0x%x
+>524	ulelong	x		future 0x%x
+>528	string	>\0		signature "%.16s"
+>544	ulelong	x		fsid.crc 0x%x
+>548	ulelong	x		fsid.edition %d
+>552	ulelong	x		fsid.blocks %d
+>556	ulelong	x		fsid.files %d
+>560	string	>\0		name "%.16s"
 
 
 Hacker Notes
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/filesystems/devfs/ChangeLog linux/Documentation/filesystems/devfs/ChangeLog
--- linux.orig/Documentation/filesystems/devfs/ChangeLog	Mon Feb 25 19:37:51 2002
+++ linux/Documentation/filesystems/devfs/ChangeLog	Tue May 28 22:39:17 2002
@@ -1880,3 +1880,59 @@
 - Updated README from master HTML file
 
 - Fixed kdev_none macro in include/linux/kdev_t.h
+===============================================================================
+Changes for patch v199.9
+
+- Added KERN_* to remaining messages
+
+- Cleaned up declaration of <stat_read>
+
+- Updated README from master HTML file
+===============================================================================
+Changes for patch v199.10
+
+- Changed <devfs_rmdir> to allow later additions if not yet empty
+
+- Added calls to <devfs_register_partitions> in drivers/block/blkpc.c
+  <add_partition> and <del_partition>
+
+- Updated README from master HTML file
+
+- Fixed bug in <devfs_alloc_unique_number>: was clearing beyond
+  bitfield
+
+- Fixed bitfield data type for <devfs_*alloc_devnum>
+
+- Made major bitfield type and initialiser 64 bit safe
+===============================================================================
+Changes for patch v199.11
+
+- Ported to kernel 2.4.19-pre5
+
+- Updated README from master HTML file
+===============================================================================
+Changes for patch v199.12
+
+- Updated README from master HTML file
+
+- Changed fs/devfs/util.c to kdev_t compatibility macros
+===============================================================================
+Changes for patch v199.13
+
+- Updated fs/devfs/util.c to fix shift warning on 64 bit machines
+  Thanks to Anton Blanchard <anton@samba.org>
+
+- Updated README from master HTML file
+
+- Do not put miscellaneous character devices in /dev/misc if they
+  specify their own directory (i.e. contain a '/' character)
+===============================================================================
+Changes for patch v199.14
+
+- Copied macro for error messages from fs/devfs/base.c to
+  fs/devfs/util.c and made use of this macro
+
+- Added BKL to <devfs_open> because drivers still need it
+
+- Protected <scan_dir_for_removable> and <get_removable_partition>
+  from changing directory contents
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/filesystems/devfs/README linux/Documentation/filesystems/devfs/README
--- linux.orig/Documentation/filesystems/devfs/README	Mon Feb 25 19:37:51 2002
+++ linux/Documentation/filesystems/devfs/README	Tue May 28 22:39:25 2002
@@ -3,7 +3,7 @@
 
 Linux Devfs (Device File System) FAQ
 Richard Gooch
-20-JAN-2002
+7-APR-2002
 
 
 Document languages:
@@ -803,12 +803,19 @@
 
 add the following lines to your /etc/devfsd.conf file:
 
-REGISTER	^pt[sy]/.*	IGNORE
-CHANGE		^pt[sy]/.*	IGNORE
+REGISTER	^pt[sy]		IGNORE
+CREATE		^pt[sy]		IGNORE
+CHANGE		^pt[sy]		IGNORE
+DELETE		^pt[sy]		IGNORE
 REGISTER	.*		COPY	/dev-state/$devname $devpath
-CHANGE		.*		COPY	$devpath /dev-state/$devname
 CREATE		.*		COPY	$devpath /dev-state/$devname
+CHANGE		.*		COPY	$devpath /dev-state/$devname
+DELETE		.*		CFUNCTION GLOBAL unlink /dev-state/$devname
+RESTORE		/dev-state
 
+Note that the sample devfsd.conf file contains these lines,
+as well as other sample configurations you may find useful. See the
+devfsd distribution
 
 
 reboot.
@@ -872,7 +879,8 @@
 (for example, by starting with /etc/fstab), and then limiting the
 compatibility entries that devfsd creates.
 
-MAKE SURE YOU INSTALL DEVFSD BEFORE YOU BOOT A DEVFS-ENABLED KERNEL!
+IF YOU CONFIGURE TO MOUNT DEVFS AT BOOT, MAKE SURE YOU INSTALL DEVFSD
+BEFORE YOU BOOT A DEVFS-ENABLED KERNEL!
 
 Now that devfs has gone into the 2.3.46 kernel, I'm getting a lot of
 reports back. Many of these are because people are trying to run
@@ -1565,6 +1573,38 @@
 the existence of the entry should be relied upon.
 
 
+When I start devfsd, I see the error:
+Error opening file: ".devfsd"   No such file or directory?
+
+This means that devfs is not mounted. Make sure you have devfs mounted.
+
+
+How do I mount devfs?
+
+First make sure you have devfs compiled into your kernel (see
+above). Then you will either need to:
+
+set CONFIG_DEVFS_MOUNT=y in your kernel config
+pass devfs=mount to your boot loader
+mount devfs manually in your boot scripts with:
+mount -t none devfs /dev
+
+
+
+Mount by volume LABEL=<label> doesn't work with
+devfs
+
+Most probably you are not mounting devfs onto /dev. What
+happens is that if your kernel config has CONFIG_DEVFS_FS=y
+then the contents of /proc/partitions will have the devfs
+names (such as scsi/host0/bus0/target0/lun0/part1). The
+contents of /proc/partitions are used by mount(8) when
+mounting by volume label. If devfs is not mounted on /dev,
+then mount(8) will fail to find devices. The solution is to
+make sure that devfs is mounted on /dev. See above for how to
+do that.
+
+
 
 
 
@@ -1760,6 +1800,15 @@
 
 
 
+make sure you have enabled debugging output when configuring your
+kernel. You will need to set (at least) the following config options:
+
+CONFIG_DEVFS_DEBUG=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SLAB=y
+
+
+
 please make sure you have the latest devfs patches applied. The
 latest kernel version might not have the latest devfs patches applied
 yet (Linus is very busy)
@@ -1768,7 +1817,10 @@
 save a copy of your complete kernel logs (preferably by
 using the dmesg programme) for later inclusion in your bug
 report. You may need to use the -s switch to increase the
-internal buffer size so you can capture all the boot messages
+internal buffer size so you can capture all the boot messages.
+Don't edit or trim the dmesg output
+
+
 
 
 try booting with devfs=dall passed to the kernel boot
@@ -1925,11 +1977,7 @@
 
 A Korean translation by viatoris@nownuri.net is available at
 
-http://home.nownuri.net/~viatoris/devfs/devfs.html
-
-A newer version is under construcation at
-
-http://viatoris.new21.org/devfs/devfs.html
+http://your.destiny.pe.kr/devfs/devfs.html
 
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/i810_rng.txt linux/Documentation/i810_rng.txt
--- linux.orig/Documentation/i810_rng.txt	Thu Apr 19 16:34:05 2001
+++ linux/Documentation/i810_rng.txt	Tue May 28 22:39:29 2002
@@ -70,6 +70,10 @@
 
 Change history:
 
+	Version 0.9.7:
+	* Support other i8xx chipsets too (by adding 82801BA(M) and
+	  82801CA(M) detection)
+
 	Version 0.9.6:
 	* Internal driver cleanups, prep for 1.0.0 release.
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/ia64/IRQ-redir.txt linux/Documentation/ia64/IRQ-redir.txt
--- linux.orig/Documentation/ia64/IRQ-redir.txt	Thu Jan  1 00:00:00 1970
+++ linux/Documentation/ia64/IRQ-redir.txt	Tue May 28 22:39:18 2002
@@ -0,0 +1,69 @@
+IRQ affinity on IA64 platforms
+------------------------------
+                           07.01.2002, Erich Focht <efocht@ess.nec.de>
+
+
+By writing to /proc/irq/IRQ#/smp_affinity the interrupt routing can be
+controlled. The behavior on IA64 platforms is slightly different from
+that described in Documentation/IRQ-affinity.txt for i386 systems.
+
+Because of the usage of SAPIC mode and physical destination mode the
+IRQ target is one particular CPU and cannot be a mask of several
+CPUs. Only the first non-zero bit is taken into account.
+
+
+Usage examples:
+
+The target CPU has to be specified as a hexadecimal CPU mask. The
+first non-zero bit is the selected CPU. This format has been kept for
+compatibility reasons with i386.
+
+Set the delivery mode of interrupt 41 to fixed and route the
+interrupts to CPU #3 (logical CPU number) (2^3=0x08):
+     echo "8" >/proc/irq/41/smp_affinity
+
+Set the default route for IRQ number 41 to CPU 6 in lowest priority
+delivery mode (redirectable):
+     echo "r 40" >/proc/irq/41/smp_affinity
+
+The output of the command
+     cat /proc/irq/IRQ#/smp_affinity
+gives the target CPU mask for the specified interrupt vector. If the CPU
+mask is preceeded by the character "r", the interrupt is redirectable
+(i.e. lowest priority mode routing is used), otherwise its route is
+fixed.
+
+
+
+Initialization and default behavior:
+
+If the platform features IRQ redirection (info provided by SAL) all
+IO-SAPIC interrupts are initialized with CPU#0 as their default target
+and the routing is the so called "lowest priority mode" (actually
+fixed SAPIC mode with hint). The XTP chipset registers are used as hints
+for the IRQ routing. Currently in Linux XTP registers can have three
+values:
+	- minimal for an idle task,
+	- normal if any other task runs,
+	- maximal if the CPU is going to be switched off.
+The IRQ is routed to the CPU with lowest XTP register value, the
+search begins at the default CPU. Therefore most of the interrupts
+will be handled by CPU #0.
+
+If the platform doesn't feature interrupt redirection IOSAPIC fixed
+routing is used. The target CPUs are distributed in a round robin
+manner. IRQs will be routed only to the selected target CPUs. Check
+with
+        cat /proc/interrupts
+
+
+
+Comments:
+
+On large (multi-node) systems it is recommended to route the IRQs to
+the node to which the corresponding device is connected.
+For systems like the NEC AzusA we get IRQ node-affinity for free. This
+is because usually the chipsets on each node redirect the interrupts
+only to their own CPUs (as they cannot see the XTP registers on the
+other nodes).
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/isdn/README.HiSax linux/Documentation/isdn/README.HiSax
--- linux.orig/Documentation/isdn/README.HiSax	Mon Aug 13 23:35:28 2001
+++ linux/Documentation/isdn/README.HiSax	Tue May 28 22:39:17 2002
@@ -52,6 +52,7 @@
 Sedlbauer Speed Star/Speed Star2 (PCMCIA)
 Sedlbauer ISDN-Controller PC/104
 USR Sportster internal TA (compatible Stollmann tina-pp V3)
+USR internal TA PCI
 ith Kommunikationstechnik GmbH MIC 16 ISA card
 Traverse Technologie NETjet PCI S0 card and NETspider U card
 Ovislink ISDN sc100-p card (NETjet driver)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/kernel-doc-nano-HOWTO.txt linux/Documentation/kernel-doc-nano-HOWTO.txt
--- linux.orig/Documentation/kernel-doc-nano-HOWTO.txt	Sat Sep  8 01:15:17 2001
+++ linux/Documentation/kernel-doc-nano-HOWTO.txt	Tue May 28 22:39:26 2002
@@ -73,10 +73,10 @@
 mkdir $ARGV[0],0777;
 $state = 0;
 while (<STDIN>) {
-    if (/^\.TH \"[^\"]*\" 4 \"([^\"]*)\"/) {
+    if (/^\.TH \"[^\"]*\" (\d) \"([^\"]*)\"/) {
 	if ($state == 1) { close OUT }
 	$state = 1;
-	$fn = "$ARGV[0]/$1.4";
+	$fn = "$ARGV[0]/$2.$1";
 	print STDERR "Creating $fn\n";
 	open OUT, ">$fn" or die "can't open $fn: $!\n";
 	print OUT $_;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/kernel-parameters.txt linux/Documentation/kernel-parameters.txt
--- linux.orig/Documentation/kernel-parameters.txt	Mon Feb 25 19:37:51 2002
+++ linux/Documentation/kernel-parameters.txt	Tue May 28 22:39:28 2002
@@ -68,6 +68,8 @@
 	53c7xx=		[HW,SCSI] Amiga SCSI controllers.
 
 	acpi=		[HW,ACPI] Advanced Configuration and Power Interface 
+
+	acpismp=force	[IA-32] Early setup parse and use ACPI SMP table.
  
 	ad1816=		[HW,SOUND]
 
@@ -378,6 +380,8 @@
 	nohlt		[BUGS=ARM]
  
 	no-hlt		[BUGS=ix86]
+
+	noht		[SMP,IA-32] Disables P4 Xeon(tm) HyperThreading.
 
 	noisapnp	[ISAPNP] Disables ISA PnP code.
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/nbd.txt linux/Documentation/nbd.txt
--- linux.orig/Documentation/nbd.txt	Thu Aug  5 21:34:01 1999
+++ linux/Documentation/nbd.txt	Tue May 28 22:39:30 2002
@@ -54,4 +54,4 @@
   ...                 in case of read operation with no error,
                       this is immediately followed len bytes of data
 
-   For more information, look at http://atrey.karlin.mff.cuni.cz/~pavel.
+   For more information, look at http://nbd.sf.net/.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/networking/3c359.txt linux/Documentation/networking/3c359.txt
--- linux.orig/Documentation/networking/3c359.txt	Thu Jan  1 00:00:00 1970
+++ linux/Documentation/networking/3c359.txt	Tue May 28 22:39:20 2002
@@ -0,0 +1,58 @@
+
+3COM PCI TOKEN LINK VELOCITY XL TOKEN RING CARDS README
+
+Release 0.9.0 - Release   
+	Jul 17th 2000 Mike Phillips 
+
+	1.2.0 - Final
+	Feb 17th 2002 Mike Phillips 
+	Updated for submission to the 2.4.x kernel.
+
+Thanks:
+	Terry Murphy from 3Com for tech docs and support,
+	Adam D. Ligas for testing the driver.
+ 
+Note:
+	This driver will NOT work with the 3C339 Token Ring cards, you need
+to use the tms380 driver instead.
+
+Options:
+
+The driver accepts three options: ringspeed, pkt_buf_sz and message_level.
+
+These options can be specified differently for each card found. 
+
+ringspeed:  Has one of three settings 0 (default), 4 or 16.  0 will 
+make the card autosense the ringspeed and join at the appropriate speed, 
+this will be the default option for most people.  4 or 16 allow you to 
+explicitly force the card to operate at a certain speed.  The card will fail 
+if you try to insert it at the wrong speed. (Although some hubs will allow 
+this so be *very* careful).  The main purpose for explicitly setting the ring
+speed is for when the card is first on the ring.  In autosense mode, if the card
+cannot detect any active monitors on the ring it will open at the same speed as
+its last opening. This can be hazardous if this speed does not match the speed
+you want the ring to operate at.  
+
+pkt_buf_sz:  This is this initial receive buffer allocation size.  This will
+default to 4096 if no value is entered. You may increase performance of the 
+driver by setting this to a value larger than the network packet size, although
+the driver now re-sizes buffers based on MTU settings as well. 
+
+message_level: Controls level of messages created by the driver. Defaults to 0:
+which only displays start-up and critical messages.  Presently any non-zero 
+value will display all soft messages as well.  NB This does not turn 
+debuging messages on, that must be done by modified the source code.
+
+Variable MTU size:
+
+The driver can handle a MTU size upto either 4500 or 18000 depending upon 
+ring speed.  The driver also changes the size of the receive buffers as part
+of the mtu re-sizing, so if you set mtu = 18000, you will need to be able
+to allocate 16 * (sk_buff with 18000 buffer size) call it 18500 bytes per ring 
+position = 296,000 bytes of memory space, plus of course anything 
+necessary for the tx sk_buff's.  Remember this is per card, so if you are
+building routers, gateway's etc, you could start to use a lot of memory
+real fast.
+
+2/17/02 Mike Phillips
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/networking/3c509.txt linux/Documentation/networking/3c509.txt
--- linux.orig/Documentation/networking/3c509.txt	Thu Jan  1 00:00:00 1970
+++ linux/Documentation/networking/3c509.txt	Tue May 28 22:39:26 2002
@@ -0,0 +1,210 @@
+Linux and the 3Com EtherLink III Series Ethercards (driver v1.18c and higher)
+----------------------------------------------------------------------------
+
+This file contains the instructions and caveats for v1.18c and higher versions
+of the 3c509 driver. You should not use the driver without reading this file.
+
+release 1.0
+28 February 2002
+Current maintainer (corrections to):
+  David Ruggiero <jdr@farfalle.com>
+
+----------------------------------------------------------------------------
+
+(0) Introduction
+
+The following are notes and information on using the 3Com EtherLink III series
+ethercards in Linux. These cards are commonly known by the most widely-used
+card's 3Com model number, 3c509. They are all 10mb/s ISA-bus cards and shouldn't
+be (but sometimes are) confused with the similarly-numbered PCI-bus "3c905"
+(aka "Vortex" or "Boomerang") series.  Kernel support for the 3c509 family is
+provided by the module 3c509.c, which has code to support all of the following
+models:
+
+  3c509 (original ISA card)
+  3c509B (later revision of the ISA card; supports full-duplex)
+  3c589 (PCMCIA)
+  3c589B (later revision of the 3c589; supports full-duplex)
+  3c529 (MCA)
+  3c579 (EISA)
+
+Large portions of this documentation were heavily borrowed from the guide
+written the original author of the 3c509 driver, Donald Becker. The master
+copy of that document, which contains notes on older versions of the driver,
+currently resides on Scyld web server: http://www.scyld.com/network/3c509.html.
+
+
+(1) Special Driver Features
+
+Overriding card settings
+
+The driver allows boot- or load-time overriding of the card's detected IOADDR,
+IRQ, and transceiver settings, although this capability shouldn't generally be
+needed except to enable full-duplex mode (see below). An example of the syntax
+for LILO parameters for doing this:
+
+    ether=10,0x310,3,0x3c509,eth0 
+
+This configures the first found 3c509 card for IRQ 10, base I/O 0x310, and
+transceiver type 3 (10base2). The flag "0x3c509" must be set to avoid conflicts
+with other card types when overriding the I/O address. When the driver is
+loaded as a module, only the IRQ and transceiver setting may be overridden.
+For example, setting two cards to 10base2/IRQ10 and AUI/IRQ11 is done by using
+the xcvr and irq module options:
+
+   options 3c509 xcvr=3,3 irq=10,11
+
+
+(2) Full-duplex mode
+
+The v1.18c driver added support for the 3c509B's full-duplex capabilities.
+In order to enable and successfully use full-duplex mode, three conditions
+must be met: 
+
+(a) You must have a Etherlink III card model whose hardware supports full-
+duplex operations. Currently, the only members of the 3c509 family that are
+positively known to support full-duplex are the 3c509B (ISA bus) and 3c589B
+(PCMCIA) cards. Cards without the "B" model designation do *not* support
+full-duplex mode; these include the original 3c509 (no "B"), the original
+3c589, the 3c529 (MCA bus), and the 3c579 (EISA bus).
+
+(b) You must be using your card's 10baseT transceiver (i.e., the RJ-45
+connector), not its AUI (thick-net) or 10base2 (thin-net/coax) interfaces.
+AUI and 10base2 network cabling is physically incapable of full-duplex
+operation.
+
+(c) Most importantly, your 3c509B must be connected to a link partner that is
+itself full-duplex capable. This is almost certainly one of two things: a full-
+duplex-capable  Ethernet switch (*not* a hub), or a full-duplex-capable NIC on
+another system that's connected directly to the 3c509B via a crossover cable.
+ 
+/////Extremely important caution concerning full-duplex mode/////
+Understand that the 3c509B's hardware's full-duplex support is much more
+limited than that provide by more modern network interface cards. Although
+at the physical layer of the network it fully supports full-duplex operation,
+the card was designed before the current Ethernet auto-negotiation (N-way)
+spec was written. This means that the 3c509B family ***cannot and will not
+auto-negotiate a full-duplex connection with its link partner under any
+circumstances, no matter how it is initialized***. If the full-duplex mode
+of the 3c509B is enabled, its link partner will very likely need to be
+independently _forced_ into full-duplex mode as well; otherwise various nasty
+failures will occur - at the very least, you'll see massive numbers of packet
+collisions. This is one of very rare circumstances where disabling auto-
+negotiation and forcing the duplex mode of a network interface card or switch
+would ever be necessary or desirable.
+
+
+(3) Available Transceiver Types
+
+For versions of the driver v1.18c and above, the available transceiver types are:
+ 
+0  transceiver type from EEPROM config (normally 10baseT); force half-duplex
+1  AUI (thick-net / DB15 connector)
+2  (undefined)
+3  10base2 (thin-net == coax / BNC connector)
+4  10baseT (RJ-45 connector); force half-duplex mode
+8  transceiver type and duplex mode taken from card's EEPROM config settings
+12 10baseT (RJ-45 connector); force full-duplex mode
+
+Prior to driver version 1.18c, only tranceiver codes 0-4 were supported. Note
+that the new transceiver codes 8 and 12 are the *only* ones that will enable
+full-duplex mode, no matter what the card's detected EEPROM settings might be.
+This insured that merely upgrading the driver from an earlier version would
+never automatically enable full-duplex mode in an existing installation;
+it must always be explicitly enabled via one of these code in order to be
+activated.
+  
+
+(4a) Interpretation of error messages and common problems
+
+Error Messages
+
+eth0: Infinite loop in interrupt, status 2011. 
+These are "mostly harmless" message indicating that the driver had too much
+work during that interrupt cycle. With a status of 0x2011 you are receiving
+packets faster than they can be removed from the card. This should be rare
+or impossible in normal operation. Possible causes of this error report are:
+ 
+   - a "green" mode enabled that slows the processor down when there is no
+     keyboard activitiy. 
+
+   - some other device or device driver hogging the bus or disabling interrupts.
+     Check /proc/interrupts for excessive interrupt counts. The timer tick
+     interrupt should always be incrementing faster than the others. 
+
+No received packets 
+If a 3c509, 3c562 or 3c589 can successfully transmit packets, but never
+receives packets (as reported by /proc/net/dev or 'ifconfig') you likely
+have an interrupt line problem. Check /proc/interrupts to verify that the
+card is actually generating interrupts. If the interrupt count is not
+increasing you likely have a physical conflict with two devices trying to
+use the same ISA IRQ line. The common conflict is with a sound card on IRQ10
+or IRQ5, and the easiest solution is to move the 3c509 to a different
+interrupt line. If the device is receiving packets but 'ping' doesn't work,
+you have a routing problem.
+
+Tx Carrier Errors Reported in /proc/net/dev 
+If an EtherLink III appears to transmit packets, but the "Tx carrier errors"
+field in /proc/net/dev increments as quickly as the Tx packet count, you
+likely have an unterminated network or the incorrect media tranceiver selected. 
+
+3c509B card is not detected on machines with an ISA PnP BIOS. 
+While the updated driver works with most PnP BIOS programs, it does not work
+with all. This can be fixed by disabling PnP support using the 3Com-supplied
+setup program. 
+
+3c509 card is not detected on overclocked machines 
+Increase the delay time in id_read_eeprom() from the current value, 500,
+to an absurdly high value, such as 5000. 
+
+
+(4b) Decoding Status and Error Messages
+
+The bits in the main status register are: 
+
+value 	description
+0x01 	Interrupt latch
+0x02 	Tx overrun, or Rx underrun
+0x04 	Tx complete
+0x08 	Tx FIFO room available
+0x10 	A complete Rx packet has arrived
+0x20 	A Rx packet has started to arrive
+0x40 	The driver has requested an interrupt
+0x80 	Statistics counter nearly full
+
+The bits in the transmit (Tx) status word are: 
+
+value 	description
+0x02 	Out-of-window collision.
+0x04 	Status stack overflow (normally impossible).
+0x08 	16 collisions.
+0x10 	Tx underrun (not enough PCI bus bandwidth).
+0x20 	Tx jabber.
+0x40 	Tx interrupt requested.
+0x80 	Status is valid (this should always be set).
+
+
+When a transmit error occurs the driver produces a status message such as 
+
+   eth0: Transmit error, Tx status register 82
+
+The two values typically seen here are:
+
+0x82 
+Out of window collision. This typically occurs when some other Ethernet
+host is incorrectly set to full duplex on a half duplex network. 
+
+0x88 
+16 collisions. This typically occurs when the network is exceptionally busy
+or when another host doesn't correctly back off after a collision. If this
+error is mixed with 0x82 errors it is the result of a host incorrectly set
+to full duplex (see above).
+
+Both of these errors are the result of network problems that should be
+corrected. They do not represent driver malfunction.
+
+
+(5) Revision history (this file)
+
+28Feb02 v1.0  DR   New; major portions based on Becker original 3c509 docs
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/networking/arcnet-hardware.txt linux/Documentation/networking/arcnet-hardware.txt
--- linux.orig/Documentation/networking/arcnet-hardware.txt	Tue Aug 22 22:21:54 2000
+++ linux/Documentation/networking/arcnet-hardware.txt	Tue May 28 22:39:26 2002
@@ -2256,7 +2256,7 @@
 When I got my two cards, one of them had this switch set to "enhanced". That
 card didn't work at all, it wasn't even recognized by the driver. The other
 card had this switch set to "compatible" and it behaved absolutely normally. I
-guess that the switch on one of the cards, must have been changed accidently
+guess that the switch on one of the cards, must have been changed accidentally
 when the card was taken out of its former host. The question remains
 unanswered, what is the purpose of the "enhanced" position?
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/networking/bonding.txt linux/Documentation/networking/bonding.txt
--- linux.orig/Documentation/networking/bonding.txt	Wed Nov  7 22:39:36 2001
+++ linux/Documentation/networking/bonding.txt	Tue May 28 22:39:21 2002
@@ -271,7 +271,7 @@
 	
 	If you wish to change the MAC address, you can set it with ifconfig:
 
-	  # ifconfig bond0 ha ether 00:11:22:33:44:55
+	  # ifconfig bond0 hw ether 00:11:22:33:44:55
 
 	The MAC address can be also changed by bringing down/up the device
 	and then changing its slaves (or their order):
@@ -503,7 +503,7 @@
 Resources and links
 ===================
 
-Current developement on this driver is posted to:
+Current development on this driver is posted to:
  - http://www.sourceforge.net/projects/bonding/
 
 Donald Becker's Ethernet Drivers and diag programs may be found at :
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/networking/comx.txt linux/Documentation/networking/comx.txt
--- linux.orig/Documentation/networking/comx.txt	Fri Apr  6 17:42:48 2001
+++ linux/Documentation/networking/comx.txt	Tue May 28 22:39:24 2002
@@ -24,6 +24,8 @@
 LoCOMX (1x512 kbps passive board)
 MixCOM (1x512 or 2x512kbps passive board with a hardware watchdog an
 	optional BRI interface and optional flashROM (1-32M))
+SliceCOM	(1x2Mbps channelized E1 board)
+PciCOM	(X21)
 
 At the moment of writing this document, the (Cisco)-HDLC, LAPB, SyncPPP and
 Frame Relay (DTE, rfc1294 IP encapsulation with partially implemented Q933a 
@@ -72,7 +74,7 @@
 To create the interface 'comx0' which is the first channel of a COMX card:
 
 insmod comx 
-# insmod comx-hw-comx ; insmod comx-proto-hdlc  (these are usually
+# insmod comx-hw-comx ; insmod comx-proto-ppp  (these are usually
 autoloaded if you use the kernel module loader)
 
 mkdir /proc/comx/comx0
@@ -141,47 +143,45 @@
 The MixCOM board doesn't require firmware, the driver communicates with
 it through I/O ports. You can have three of these cards in one machine.
 
-THE HDLC LINE PROTOCOL DRIVER
+THE SLICECOM DRIVER
+
+The SliceCOM board doesn't require firmware. You can have 4 of these cards
+in one machine. The driver doesn't (yet) support shared interrupts, so
+you will need a separate IRQ line for every board.
+Read linux/Documentation/networking/slicecom.txt for help on configuring
+this adapter.
+
+THE HDLC/PPP LINE PROTOCOL DRIVER
+
+The HDLC/SyncPPP line protocol driver uses the kernel's built-in syncppp
+driver (syncppp.o). You don't have to manually select syncppp.o when building
+the kernel, the dependencies compile it in automatically.
 
-There's only one configurable parameter with this protocol: the 'keepalive'
-value. You can set this in seconds or set to 'off'. Agree with the administrator
-of your peer router on this setting. The default is 10 (seconds).
 
-EXAMPLE
 
+
+EXAMPLE
 (setting up hw parameters, see above)
+
+# using HDLC:
 echo hdlc >/proc/comx/comx0/protocol
 echo 10 >/proc/comx/comx0/keepalive	<- not necessary, 10 is the default
 ifconfig comx0 1.2.3.4 pointopoint 5.6.7.8 netmask 255.255.255.255
 
-
-THE PPP LINE PROTOCOL DRIVER
-
-To use this driver, you have to have ppp-2.3.4, and have a modified version of
-pppd (this pppd will work as async pppd to, the modifiactions merely relax 
-some restricions in order to be able to use non-async lines too.
-If configured, this driver can use Van Jacobson TCP header compression (you'll
-need the slhc.o module for this).
-Additionally to use this protocol, enable async ppp in your kernel config, and
-create the comx device special files in /dev. They're character special files
-with major 88, and their names must be the same as their network interface
-counterparts (i.e /dev/comx0 with minor 0 corresponds interface comx0 and so
-on).
-
-EXAMPLE
-
 (setting up hw parameters, see above)
+
+# using PPP:
 echo ppp >/proc/comx/comx0/protocol
 ifconfig comx0 up
-pppd comx0 1.2.3.4:5.6.7.8 persist	<- with this option pppd won't exit
-					   when the line goes down
+ifconfig comx0 1.2.3.4 pointopoint 5.6.7.8 netmask 255.255.255.255
+
 
 THE LAPB LINE PROTOCOL DRIVER
 
 For this, you'll need to configure LAPB support (See 'LAPB Data Link Driver' in
 'Network options' section) into your kernel (thanks to Jonathan Naylor for his 
 excellent implementation). 
-comxlapb.o provides the following files in the appropriate directory
+comx-proto-lapb.o provides the following files in the appropriate directory
 (the default values in parens): t1 (5), t2 (1), n2 (20), mode (DTE, STD) and
 window (7). Agree with the administrator of your peer router on these
 settings (most people use defaults, but you have to know if you are DTE or
@@ -221,7 +221,7 @@
 
 boardtype:
 Type of the hardware. Valid values are:
- 'comx', 'hicomx', 'locomx', 'cmx'.
+ 'comx', 'hicomx', 'locomx', 'cmx', 'slicecom'.
 
 protocol:
 Data-link protocol on this channel. Can be: HDLC, LAPB, PPP, FRAD
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/networking/dl2k.txt linux/Documentation/networking/dl2k.txt
--- linux.orig/Documentation/networking/dl2k.txt	Mon Feb 25 19:37:51 2002
+++ linux/Documentation/networking/dl2k.txt	Tue May 28 22:39:17 2002
@@ -1,7 +1,7 @@
 
     D-Link DL2000-based Gigabit Ethernet Adapter Installation
     for Linux
-    Jan 02, 2002
+    Jan 29, 2002
 
 Contents
 ========
@@ -199,8 +199,8 @@
 				  6          	1000Mbps full duplex.
 
 				  By default, the NIC operates at autosense.
-				  Note that only 1000mbps_fd and 1000mbps_hd
-				  types are available for fiber adapter.
+				  1000mbps_fd and 1000mbps_hd types are only
+				  available for fiber adapter.
 
 vlan=[0|1]			- Specifies the VLAN ID. If vlan=0, the
 				  Virtual Local Area Network (VLAN) function is
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/networking/driver.txt linux/Documentation/networking/driver.txt
--- linux.orig/Documentation/networking/driver.txt	Thu Jan  1 00:00:00 1970
+++ linux/Documentation/networking/driver.txt	Tue May 28 22:39:15 2002
@@ -0,0 +1,84 @@
+Documents about softnet driver issues in general can be found
+at:
+
+	http://www.firstfloor.org/~andi/softnet/
+
+Transmit path guidelines:
+
+1) The hard_start_xmit method must never return '1' under any
+   normal circumstances.  It is considered a hard error unless
+   there is no way your device can tell ahead of time when it's
+   transmit function will become busy.
+
+   Instead it must maintain the queue properly.  For example,
+   for a driver implementing scatter-gather this means:
+
+	static int drv_hard_start_xmit(struct sk_buff *skb,
+		   		       struct net_device *dev)
+	{
+		struct drv *dp = dev->priv;
+
+		lock_tx(dp);
+		...
+		/* This is a hard error log it. */
+		if (TX_BUFFS_AVAIL(dp) <= (skb_shinfo(skb)->nr_frags + 1)) {
+			netif_stop_queue(dev);
+			unlock_tx(dp);
+			printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
+			       dev->name);
+			return 1;
+		}
+
+		... queue packet to card ...
+		... update tx consumer index ...
+
+		if (TX_BUFFS_AVAIL(dp) <= (MAX_SKB_FRAGS + 1))
+			netif_stop_queue(dev);
+
+		...
+		unlock_tx(dp);
+		...
+	}
+
+   And then at the end of your TX reclaimation event handling:
+
+	if (netif_queue_stopped(dp->dev) &&
+            TX_BUFFS_AVAIL(dp) > (MAX_SKB_FRAGS + 1))
+		netif_wake_queue(dp->dev);
+
+   For a non-scatter-gather supporting card, the three tests simply become:
+
+		/* This is a hard error log it. */
+		if (TX_BUFFS_AVAIL(dp) <= 0)
+
+   and:
+
+		if (TX_BUFFS_AVAIL(dp) == 0)
+
+   and:
+
+	if (netif_queue_stopped(dp->dev) &&
+            TX_BUFFS_AVAIL(dp) > 0)
+		netif_wake_queue(dp->dev);
+
+2) Do not forget to update netdev->trans_start to jiffies after
+   each new tx packet is given to the hardware.
+
+3) Do not forget that once you return 0 from your hard_start_xmit
+   method, it is your driver's responsibility to free up the SKB
+   and in some finite amount of time.
+
+   For example, this means that it is not allowed for your TX
+   mitigation scheme to let TX packets "hang out" in the TX
+   ring unreclaimed forever if no new TX packets are sent.
+   This error can deadlock sockets waiting for send buffer room
+   to be freed up.
+
+   If you return 1 from the hard_start_xmit method, you must not keep
+   any reference to that SKB and you must not attempt to free it up.
+
+Probing guidelines:
+
+1) Any hardware layer address you obtain for your device should
+   be verified.  For example, for ethernet check it with
+   linux/etherdevice.h:is_valid_ether_addr()
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/networking/ifenslave.c linux/Documentation/networking/ifenslave.c
--- linux.orig/Documentation/networking/ifenslave.c	Wed Nov  7 22:39:36 2001
+++ linux/Documentation/networking/ifenslave.c	Tue May 28 22:39:18 2002
@@ -38,6 +38,9 @@
  *         take care of this itself
  *       - Try the SIOC*** versions of the bonding ioctls before using the
  *         old versions
+ *    - 2002/02/18 Erik Habbinga <erik_habbinga @ hp dot com> :
+ *       - ifr2.ifr_flags was not initialized in the hwaddr_notset case,
+ *         SIOCGIFFLAGS now called before hwaddr_notset test
  */
 
 static char *version =
@@ -288,19 +291,19 @@
 			     hwaddr from it's first slave.
 			   - if !hwaddr_notset, assign the master's hwaddr to each slave
 			*/
-	
+
+			strncpy(ifr2.ifr_name, slave_ifname, IFNAMSIZ);
+			if (ioctl(skfd, SIOCGIFFLAGS, &ifr2) < 0) {
+				int saved_errno = errno;
+				fprintf(stderr, "SIOCGIFFLAGS on %s failed: %s\n", slave_ifname,
+						strerror(saved_errno));
+				return 1;
+			}
+
 			if (hwaddr_notset) { /* we do nothing */
 
 			}
 			else {  /* we'll assign master's hwaddr to this slave */
-				strncpy(ifr2.ifr_name, slave_ifname, IFNAMSIZ);
-				if (ioctl(skfd, SIOCGIFFLAGS, &ifr2) < 0) {
-					int saved_errno = errno;
-					fprintf(stderr, "SIOCGIFFLAGS on %s failed: %s\n", slave_ifname,
-							strerror(saved_errno));
-					return 1;
-				}
-	
 				if (ifr2.ifr_flags & IFF_UP) {
 					ifr2.ifr_flags &= ~IFF_UP;
 					if (ioctl(skfd, SIOCSIFFLAGS, &ifr2) < 0) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/networking/ip-sysctl.txt linux/Documentation/networking/ip-sysctl.txt
--- linux.orig/Documentation/networking/ip-sysctl.txt	Mon Feb 25 19:37:51 2002
+++ linux/Documentation/networking/ip-sysctl.txt	Tue May 28 22:39:25 2002
@@ -126,7 +126,13 @@
 	if network conditions require more than default value.
 
 tcp_tw_recycle - BOOLEAN
-	Enable fast recycling TIME-WAIT sockets. Default value is 1.
+	Enable fast recycling TIME-WAIT sockets. Default value is 0.
+	It should not be changed without advice/request of technical
+	experts.
+
+tcp_tw_reuse - BOOLEAN
+	Allow to reuse TIME-WAIT sockets for new connections when it is
+	safe from protocol viewpoint. Default value is 0.
 	It should not be changed without advice/request of technical
 	experts.
 
@@ -182,10 +188,7 @@
 	still did not receive an acknowledgement from connecting client.
 	Default value is 1024 for systems with more than 128Mb of memory,
 	and 128 for low memory machines. If server suffers of overload,
-	try to increase this number. Warning! If you make it greater
-	than 1024, it would be better to change TCP_SYNQ_HSIZE in
-	include/net/tcp.h to keep TCP_SYNQ_HSIZE*16<=tcp_max_syn_backlog
-	and to recompile kernel.
+	try to increase this number.
 
 tcp_window_scaling - BOOLEAN
 	Enable window scaling as defined in RFC1323.
@@ -357,6 +360,17 @@
 mc_forwarding - BOOLEAN
 	Do multicast routing. The kernel needs to be compiled with CONFIG_MROUTE
 	and a multicast routing daemon is required.
+
+medium_id - INTEGER
+	Integer value used to differentiate the devices by the medium they
+	are attached to. Two devices can have different id values when
+	the broadcast packets are received only on one of them.
+	The default value 0 means that the device is the only interface
+	to its medium, value of -1 means that medium is not known.
+	
+	Currently, it is used to change the proxy_arp behavior:
+	the proxy_arp feature is enabled for packets forwarded between
+	two devices attached to different media.
 
 proxy_arp - BOOLEAN
 	Do proxy arp.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/networking/pktgen.txt linux/Documentation/networking/pktgen.txt
--- linux.orig/Documentation/networking/pktgen.txt	Thu Jan  1 00:00:00 1970
+++ linux/Documentation/networking/pktgen.txt	Tue May 28 22:39:23 2002
@@ -0,0 +1,50 @@
+How to use the Linux packet generator module.
+
+1. Enable CONFIG_NET_PKTGEN to compile and build pktgen.o, install it
+   in the place where insmod may find it.
+2. Cut script "ipg" (see below).
+3. Edit script to set preferred device and destination IP address.
+4. Run in shell: ". ipg"
+5. After this two commands are defined:
+   A. "pg" to start generator and to get results.
+   B. "pgset" to change generator parameters. F.e.
+      pgset "multiskb 1"      use multiple SKBs for packet generation
+      pgset "multiskb 0"      use single SKB for all transmits
+      pgset "pkt_size 9014"   sets packet size to 9014
+      pgset "frags 5"         packet will consist of 5 fragments
+      pgset "count 200000"    sets number of packets to send
+      pgset "ipg 5000"        sets artificial gap inserted between packets
+                              to 5000 nanoseconds
+      pgset "dst 10.0.0.1"    sets IP destination address
+                              (BEWARE! This generator is very aggressive!)
+      pgset "dstmac 00:00:00:00:00:00"    sets MAC destination address
+      pgset stop    	      aborts injection
+      
+  Also, ^C aborts generator.
+
+---- cut here
+
+#! /bin/sh
+
+modprobe pktgen.o
+
+function pgset() {
+    local result
+
+    echo $1 > /proc/net/pg
+
+    result=`cat /proc/net/pg | fgrep "Result: OK:"`
+    if [ "$result" = "" ]; then
+         cat /proc/net/pg | fgrep Result:
+    fi
+}
+
+function pg() {
+    echo inject > /proc/net/pg
+    cat /proc/net/pg
+}
+
+pgset "odev eth0"
+pgset "dst 0.0.0.0"
+
+---- cut here
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/networking/ppp_generic.txt linux/Documentation/networking/ppp_generic.txt
--- linux.orig/Documentation/networking/ppp_generic.txt	Thu Jan  1 00:00:00 1970
+++ linux/Documentation/networking/ppp_generic.txt	Tue May 28 22:39:18 2002
@@ -0,0 +1,432 @@
+		PPP Generic Driver and Channel Interface
+		----------------------------------------
+
+			    Paul Mackerras
+			   paulus@samba.org
+			      7 Feb 2002
+
+The generic PPP driver in linux-2.4 provides an implementation of the
+functionality which is of use in any PPP implementation, including:
+
+* the network interface unit (ppp0 etc.)
+* the interface to the networking code
+* PPP multilink: splitting datagrams between multiple links, and
+  ordering and combining received fragments
+* the interface to pppd, via a /dev/ppp character device
+* packet compression and decompression
+* TCP/IP header compression and decompression
+* detecting network traffic for demand dialling and for idle timeouts
+* simple packet filtering
+
+For sending and receiving PPP frames, the generic PPP driver calls on
+the services of PPP `channels'.  A PPP channel encapsulates a
+mechanism for transporting PPP frames from one machine to another.  A
+PPP channel implementation can be arbitrarily complex internally but
+has a very simple interface with the generic PPP code: it merely has
+to be able to send PPP frames, receive PPP frames, and optionally
+handle ioctl requests.  Currently there are PPP channel
+implementations for asynchronous serial ports, synchronous serial
+ports, and for PPP over ethernet.
+
+This architecture makes it possible to implement PPP multilink in a
+natural and straightforward way, by allowing more than one channel to
+be linked to each ppp network interface unit.  The generic layer is
+responsible for splitting datagrams on transmit and recombining them
+on receive.
+
+
+PPP channel API
+---------------
+
+See include/linux/ppp_channel.h for the declaration of the types and
+functions used to communicate between the generic PPP layer and PPP
+channels.
+
+Each channel has to provide two functions to the generic PPP layer,
+via the ppp_channel.ops pointer:
+
+* start_xmit() is called by the generic layer when it has a frame to
+  send.  The channel has the option of rejecting the frame for
+  flow-control reasons.  In this case, start_xmit() should return 0
+  and the channel should call the ppp_output_wakeup() function at a
+  later time when it can accept frames again, and the generic layer
+  will then attempt to retransmit the rejected frame(s).  If the frame
+  is accepted, the start_xmit() function should return 1.
+
+* ioctl() provides an interface which can be used by a user-space
+  program to control aspects of the channel's behaviour.  This
+  procedure will be called when a user-space program does an ioctl
+  system call on an instance of /dev/ppp which is bound to the
+  channel.  (Usually it would only be pppd which would do this.)
+
+The generic PPP layer provides seven functions to channels:
+
+* ppp_register_channel() is called when a channel has been created, to
+  notify the PPP generic layer of its presence.  For example, setting
+  a serial port to the PPPDISC line discipline causes the ppp_async
+  channel code to call this function.
+
+* ppp_unregister_channel() is called when a channel is to be
+  destroyed.  For example, the ppp_async channel code calls this when
+  a hangup is detected on the serial port.
+
+* ppp_output_wakeup() is called by a channel when it has previously
+  rejected a call to its start_xmit function, and can now accept more
+  packets.
+
+* ppp_input() is called by a channel when it has received a complete
+  PPP frame.
+
+* ppp_input_error() is called by a channel when it has detected that a
+  frame has been lost or dropped (for example, because of a FCS (frame
+  check sequence) error).
+
+* ppp_channel_index() returns the channel index assigned by the PPP
+  generic layer to this channel.  The channel should provide some way
+  (e.g. an ioctl) to transmit this back to user-space, as user-space
+  will need it to attach an instance of /dev/ppp to this channel.
+
+* ppp_unit_number() returns the unit number of the ppp network
+  interface to which this channel is connected, or -1 if the channel
+  is not connected.
+
+Connecting a channel to the ppp generic layer is initiated from the
+channel code, rather than from the generic layer.  The channel is
+expected to have some way for a user-level process to control it
+independently of the ppp generic layer.  For example, with the
+ppp_async channel, this is provided by the file descriptor to the
+serial port.
+
+Generally a user-level process will initialize the underlying
+communications medium and prepare it to do PPP.  For example, with an
+async tty, this can involve setting the tty speed and modes, issuing
+modem commands, and then going through some sort of dialog with the
+remote system to invoke PPP service there.  We refer to this process
+as `discovery'.  Then the user-level process tells the medium to
+become a PPP channel and register itself with the generic PPP layer.
+The channel then has to report the channel number assigned to it back
+to the user-level process.  From that point, the PPP negotiation code
+in the PPP daemon (pppd) can take over and perform the PPP
+negotiation, accessing the channel through the /dev/ppp interface.
+
+At the interface to the PPP generic layer, PPP frames are stored in
+skbuff structures and start with the two-byte PPP protocol number.
+The frame does *not* include the 0xff `address' byte or the 0x03
+`control' byte that are optionally used in async PPP.  Nor is there
+any escaping of control characters, nor are there any FCS or framing
+characters included.  That is all the responsibility of the channel
+code, if it is needed for the particular medium.  That is, the skbuffs
+presented to the start_xmit() function contain only the 2-byte
+protocol number and the data, and the skbuffs presented to ppp_input()
+must be in the same format.
+
+The channel must provide an instance of a ppp_channel struct to
+represent the channel.  The channel is free to use the `private' field
+however it wishes.  The channel should initialize the `mtu' and
+`hdrlen' fields before calling ppp_register_channel() and not change
+them until after ppp_unregister_channel() returns.  The `mtu' field
+represents the maximum size of the data part of the PPP frames, that
+is, it does not include the 2-byte protocol number.
+
+If the channel needs some headroom in the skbuffs presented to it for
+transmission (i.e., some space free in the skbuff data area before the
+start of the PPP frame), it should set the `hdrlen' field of the
+ppp_channel struct to the amount of headroom required.  The generic
+PPP layer will attempt to provide that much headroom but the channel
+should still check if there is sufficient headroom and copy the skbuff
+if there isn't.
+
+On the input side, channels should ideally provide at least 2 bytes of
+headroom in the skbuffs presented to ppp_input().  The generic PPP
+code does not require this but will be more efficient if this is done.
+
+
+Buffering and flow control
+--------------------------
+
+The generic PPP layer has been designed to minimize the amount of data
+that it buffers in the transmit direction.  It maintains a queue of
+transmit packets for the PPP unit (network interface device) plus a
+queue of transmit packets for each attached channel.  Normally the
+transmit queue for the unit will contain at most one packet; the
+exceptions are when pppd sends packets by writing to /dev/ppp, and
+when the core networking code calls the generic layer's start_xmit()
+function with the queue stopped, i.e. when the generic layer has
+called netif_stop_queue(), which only happens on a transmit timeout.
+The start_xmit function always accepts and queues the packet which it
+is asked to transmit.
+
+Transmit packets are dequeued from the PPP unit transmit queue and
+then subjected to TCP/IP header compression and packet compression
+(Deflate or BSD-Compress compression), as appropriate.  After this
+point the packets can no longer be reordered, as the decompression
+algorithms rely on receiving compressed packets in the same order that
+they were generated.
+
+If multilink is not in use, this packet is then passed to the attached
+channel's start_xmit() function.  If the channel refuses to take
+the packet, the generic layer saves it for later transmission.  The
+generic layer will call the channel's start_xmit() function again
+when the channel calls  ppp_output_wakeup() or when the core
+networking code calls the generic layer's start_xmit() function
+again.  The generic layer contains no timeout and retransmission
+logic; it relies on the core networking code for that.
+
+If multilink is in use, the generic layer divides the packet into one
+or more fragments and puts a multilink header on each fragment.  It
+decides how many fragments to use based on the length of the packet
+and the number of channels which are potentially able to accept a
+fragment at the moment.  A channel is potentially able to accept a
+fragment if it doesn't have any fragments currently queued up for it
+to transmit.  The channel may still refuse a fragment; in this case
+the fragment is queued up for the channel to transmit later.  This
+scheme has the effect that more fragments are given to higher-
+bandwidth channels.  It also means that under light load, the generic
+layer will tend to fragment large packets across all the channels,
+thus reducing latency, while under heavy load, packets will tend to be
+transmitted as single fragments, thus reducing the overhead of
+fragmentation.
+
+
+SMP safety
+----------
+
+The PPP generic layer has been designed to be SMP-safe.  Locks are
+used around accesses to the internal data structures where necessary
+to ensure their integrity.  As part of this, the generic layer
+requires that the channels adhere to certain requirements and in turn
+provides certain guarantees to the channels.  Essentially the channels
+are required to provide the appropriate locking on the ppp_channel
+structures that form the basis of the communication between the
+channel and the generic layer.  This is because the channel provides
+the storage for the ppp_channel structure, and so the channel is
+required to provide the guarantee that this storage exists and is
+valid at the appropriate times.
+
+The generic layer requires these guarantees from the channel:
+
+* The ppp_channel object must exist from the time that
+  ppp_register_channel() is called until after the call to
+  ppp_unregister_channel() returns.
+
+* No thread may be in a call to any of ppp_input(), ppp_input_error(),
+  ppp_output_wakeup(), ppp_channel_index() or ppp_unit_number() for a
+  channel at the time that ppp_unregister_channel() is called for that
+  channel.
+
+* ppp_register_channel() and ppp_unregister_channel() must be called
+  from process context, not interrupt or softirq/BH context.
+
+* The remaining generic layer functions may be called at softirq/BH
+  level but must not be called from a hardware interrupt handler.
+
+* The generic layer may call the channel start_xmit() function at
+  softirq/BH level but will not call it at interrupt level.  Thus the
+  start_xmit() function may not block.
+
+* The generic layer will only call the channel ioctl() function in
+  process context.
+
+The generic layer provides these guarantees to the channels:
+
+* The generic layer will not call the start_xmit() function for a
+  channel while any thread is already executing in that function for
+  that channel.
+
+* The generic layer will not call the ioctl() function for a channel
+  while any thread is already executing in that function for that
+  channel.
+
+* By the time a call to ppp_unregister_channel() returns, no thread
+  will be executing in a call from the generic layer to that channel's
+  start_xmit() or ioctl() function, and the generic layer will not
+  call either of those functions subsequently.
+
+
+Interface to pppd
+-----------------
+
+The PPP generic layer exports a character device interface called
+/dev/ppp.  This is used by pppd to control PPP interface units and
+channels.  Although there is only one /dev/ppp, each open instance of
+/dev/ppp acts independently and can be attached either to a PPP unit
+or a PPP channel.  This is achieved using the file->private_data field
+to point to a separate object for each open instance of /dev/ppp.  In
+this way an effect similar to Solaris' clone open is obtained,
+allowing us to control an arbitrary number of PPP interfaces and
+channels without having to fill up /dev with hundreds of device names.
+
+When /dev/ppp is opened, a new instance is created which is initially
+unattached.  Using an ioctl call, it can then be attached to an
+existing unit, attached to a newly-created unit, or attached to an
+existing channel.  An instance attached to a unit can be used to send
+and receive PPP control frames, using the read() and write() system
+calls, along with poll() if necessary.  Similarly, an instance
+attached to a channel can be used to send and receive PPP frames on
+that channel.
+
+In multilink terms, the unit represents the bundle, while the channels
+represent the individual physical links.  Thus, a PPP frame sent by a
+write to the unit (i.e., to an instance of /dev/ppp attached to the
+unit) will be subject to bundle-level compression and to fragmentation
+across the individual links (if multilink is in use).  In contrast, a
+PPP frame sent by a write to the channel will be sent as-is on that
+channel, without any multilink header.
+
+A channel is not initially attached to any unit.  In this state it can
+be used for PPP negotiation but not for the transfer of data packets.
+It can then be connected to a PPP unit with an ioctl call, which
+makes it available to send and receive data packets for that unit.
+
+The ioctl calls which are available on an instance of /dev/ppp depend
+on whether it is unattached, attached to a PPP interface, or attached
+to a PPP channel.  The ioctl calls which are available on an
+unattached instance are:
+
+* PPPIOCNEWUNIT creates a new PPP interface and makes this /dev/ppp
+  instance the "owner" of the interface.  The argument should point to
+  an int which is the desired unit number if >= 0, or -1 to assign the
+  lowest unused unit number.  Being the owner of the interface means
+  that the interface will be shut down if this instance of /dev/ppp is
+  closed.
+
+* PPPIOCATTACH attaches this instance to an existing PPP interface.
+  The argument should point to an int containing the unit number.
+  This does not make this instance the owner of the PPP interface.
+
+* PPPIOCATTCHAN attaches this instance to an existing PPP channel.
+  The argument should point to an int containing the channel number.
+
+The ioctl calls available on an instance of /dev/ppp attached to a
+channel are:
+
+* PPPIOCDETACH detaches the instance from the channel.  This ioctl is
+  deprecated since the same effect can be achieved by closing the
+  instance.  In order to prevent possible races this ioctl will fail
+  with an EINVAL error if more than one file descriptor refers to this
+  instance (i.e. as a result of dup(), dup2() or fork()).
+
+* PPPIOCCONNECT connects this channel to a PPP interface.  The
+  argument should point to an int containing the interface unit
+  number.  It will return an EINVAL error if the channel is already
+  connected to an interface, or ENXIO if the requested interface does
+  not exist.
+
+* PPPIOCDISCONN disconnects this channel from the PPP interface that
+  it is connected to.  It will return an EINVAL error if the channel
+  is not connected to an interface.
+
+* All other ioctl commands are passed to the channel ioctl() function.
+
+The ioctl calls that are available on an instance that is attached to
+an interface unit are:
+
+* PPPIOCSMRU sets the MRU (maximum receive unit) for the interface.
+  The argument should point to an int containing the new MRU value.
+
+* PPPIOCSFLAGS sets flags which control the operation of the
+  interface.  The argument should be a pointer to an int containing
+  the new flags value.  The bits in the flags value that can be set
+  are:
+	SC_COMP_TCP		enable transmit TCP header compression
+	SC_NO_TCP_CCID		disable connection-id compression for
+				TCP header compression
+	SC_REJ_COMP_TCP		disable receive TCP header decompression
+	SC_CCP_OPEN		Compression Control Protocol (CCP) is
+				open, so inspect CCP packets
+	SC_CCP_UP		CCP is up, may (de)compress packets
+	SC_LOOP_TRAFFIC		send IP traffic to pppd
+	SC_MULTILINK		enable PPP multilink fragmentation on
+				transmitted packets
+	SC_MP_SHORTSEQ		expect short multilink sequence
+				numbers on received multilink fragments
+	SC_MP_XSHORTSEQ		transmit short multilink sequence nos.
+
+  The values of these flags are defined in <linux/if_ppp.h>.  Note
+  that the values of the SC_MULTILINK, SC_MP_SHORTSEQ and
+  SC_MP_XSHORTSEQ bits are ignored if the CONFIG_PPP_MULTILINK option
+  is not selected.
+
+* PPPIOCGFLAGS returns the value of the status/control flags for the
+  interface unit.  The argument should point to an int where the ioctl
+  will store the flags value.  As well as the values listed above for
+  PPPIOCSFLAGS, the following bits may be set in the returned value:
+	SC_COMP_RUN		CCP compressor is running
+	SC_DECOMP_RUN		CCP decompressor is running
+	SC_DC_ERROR		CCP decompressor detected non-fatal error
+	SC_DC_FERROR		CCP decompressor detected fatal error
+
+* PPPIOCSCOMPRESS sets the parameters for packet compression or
+  decompression.  The argument should point to a ppp_option_data
+  structure (defined in <linux/if_ppp.h>), which contains a
+  pointer/length pair which should describe a block of memory
+  containing a CCP option specifying a compression method and its
+  parameters.  The ppp_option_data struct also contains a `transmit'
+  field.  If this is 0, the ioctl will affect the receive path,
+  otherwise the transmit path.
+
+* PPPIOCGUNIT returns, in the int pointed to by the argument, the unit
+  number of this interface unit.
+
+* PPPIOCSDEBUG sets the debug flags for the interface to the value in
+  the int pointed to by the argument.  Only the least significant bit
+  is used; if this is 1 the generic layer will print some debug
+  messages during its operation.  This is only intended for debugging
+  the generic PPP layer code; it is generally not helpful for working
+  out why a PPP connection is failing.
+
+* PPPIOCGDEBUG returns the debug flags for the interface in the int
+  pointed to by the argument.
+
+* PPPIOCGIDLE returns the time, in seconds, since the last data
+  packets were sent and received.  The argument should point to a
+  ppp_idle structure (defined in <linux/ppp_defs.h>).  If the
+  CONFIG_PPP_FILTER option is enabled, the set of packets which reset
+  the transmit and receive idle timers is restricted to those which
+  pass the `active' packet filter.
+
+* PPPIOCSMAXCID sets the maximum connection-ID parameter (and thus the
+  number of connection slots) for the TCP header compressor and
+  decompressor.  The lower 16 bits of the int pointed to by the
+  argument specify the maximum connection-ID for the compressor.  If
+  the upper 16 bits of that int are non-zero, they specify the maximum
+  connection-ID for the decompressor, otherwise the decompressor's
+  maximum connection-ID is set to 15.
+
+* PPPIOCSNPMODE sets the network-protocol mode for a given network
+  protocol.  The argument should point to an npioctl struct (defined
+  in <linux/if_ppp.h>).  The `protocol' field gives the PPP protocol
+  number for the protocol to be affected, and the `mode' field
+  specifies what to do with packets for that protocol:
+
+	NPMODE_PASS	normal operation, transmit and receive packets
+	NPMODE_DROP	silently drop packets for this protocol
+	NPMODE_ERROR	drop packets and return an error on transmit
+	NPMODE_QUEUE	queue up packets for transmit, drop received
+			packets
+
+  At present NPMODE_ERROR and NPMODE_QUEUE have the same effect as
+  NPMODE_DROP.
+
+* PPPIOCGNPMODE returns the network-protocol mode for a given
+  protocol.  The argument should point to an npioctl struct with the
+  `protocol' field set to the PPP protocol number for the protocol of
+  interest.  On return the `mode' field will be set to the network-
+  protocol mode for that protocol.
+
+* PPPIOCSPASS and PPPIOCSACTIVE set the `pass' and `active' packet
+  filters.  These ioctls are only available if the CONFIG_PPP_FILTER
+  option is selected.  The argument should point to a sock_fprog
+  structure (defined in <linux/filter.h>) containing the compiled BPF
+  instructions for the filter.  Packets are dropped if they fail the
+  `pass' filter; otherwise, if they fail the `active' filter they are
+  passed but they do not reset the transmit or receive idle timer.
+
+* PPPIOCSMRRU enables or disables multilink processing for received
+  packets and sets the multilink MRRU (maximum reconstructed receive
+  unit).  The argument should point to an int containing the new MRRU
+  value.  If the MRRU value is 0, processing of received multilink
+  fragments is disabled.  This ioctl is only available if the
+  CONFIG_PPP_MULTILINK option is selected.
+
+Last modified: 7-feb-2002
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/networking/skfp.txt linux/Documentation/networking/skfp.txt
--- linux.orig/Documentation/networking/skfp.txt	Fri May 12 18:43:26 2000
+++ linux/Documentation/networking/skfp.txt	Tue May 28 22:39:12 2002
@@ -143,6 +143,10 @@
 (6) HISTORY
 ===========
 
+v2.07 (20020506) (In-Kernel version)
+    Fix: Transmit Descriptor struct
+    Fix: Receive Descriptor struct
+
 v2.06 (20000511) (In-Kernel version)
     New features:
 	- 64 bit support
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/networking/slicecom.hun linux/Documentation/networking/slicecom.hun
--- linux.orig/Documentation/networking/slicecom.hun	Thu Jan  1 00:00:00 1970
+++ linux/Documentation/networking/slicecom.hun	Tue May 28 22:39:16 2002
@@ -0,0 +1,371 @@
+
+SliceCOM adapter felhasznaloi dokumentacioja - 0.51 verziohoz
+
+Bartók István <bartoki@itc.hu>
+Utolso modositas: Wed Aug 29 17:26:58 CEST 2001
+
+-----------------------------------------------------------------
+
+Hasznalata:
+
+Forditas:
+
+Code maturity level options
+	[*] Prompt for development and/or incomplete code/drivers
+
+Network device support
+	Wan interfaces
+		<M> MultiGate (COMX) synchronous
+			<M> Support for MUNICH based boards: SliceCOM, PCICOM (NEW)
+			<M> Support for HDLC and syncPPP...
+
+
+A modulok betoltese:
+
+modprobe comx
+
+modprobe comx-proto-ppp		# a Cisco-HDLC es a SyncPPP protokollt is
+				# ez a modul adja
+
+modprobe comx-hw-munich		# a modul betoltodeskor azonnal jelent a
+				# syslogba a detektalt kartyakrol
+
+
+Konfiguralas:
+
+# Ezen az interfeszen Cisco-HDLC vonali protokoll fog futni
+# Az interfeszhez rendelt idoszeletek: 1,2 (128 kbit/sec-es vonal)
+# (a G.703 keretben az elso adatot vivo idoszelet az 1-es)
+#
+mkdir /proc/comx/comx0.1/
+echo slicecom	>/proc/comx/comx0.1/boardtype
+echo hdlc	>/proc/comx/comx0.1/protocol
+echo 1 2	>/proc/comx/comx0.1/timeslots
+
+
+# Ezen az interfeszen SyncPPP vonali protokoll fog futni
+# Az interfeszhez rendelt idoszelet: 3 (64 kbit/sec-es vonal)
+#
+mkdir /proc/comx/comx0.2/
+echo slicecom	>/proc/comx/comx0.2/boardtype
+echo ppp	>/proc/comx/comx0.2/protocol
+echo 3		>/proc/comx/comx0.2/timeslots
+
+...
+
+ifconfig comx0.1 up
+ifconfig comx0.2 up
+
+-----------------------------------------------------------------
+
+A COMX driverek default 20 csomagnyi transmit queue-t rendelnek a halozati
+interfeszekhez. WAN halozatokban ennel hosszabbat is szokas hasznalni
+(20 es 100 kozott), hogy a vonal kihasznaltsaga nagy terheles eseten jobb
+legyen (bar ezzel megno a varhato kesleltetes a csomagok sorban allasa miatt):
+
+# ifconfig comx0 txqueuelen 50
+
+Ezt a beallitasi lehetoseget csak az ujabb disztribuciok ifconfig parancsa
+tamogatja (amik mar a 2.2 kernelekhez keszultek, mint a RedHat 6.1 vagy a
+Debian 2.2).
+
+A 2.1-es Debian disztribuciohoz a http://www.debian.org/~rcw/2.2/netbase/
+cimrol toltheto le ujabb netbase csomag, ami mar ilyet tamogato ifconfig
+parancsot tartalmaz. Bovebben a 2.2 kernel hasznalatarol Debian 2.1 alatt:
+http://www.debian.org/releases/stable/running-kernel-2.2
+
+-----------------------------------------------------------------
+
+A kartya LED-jeinek jelentese:
+
+piros	- eg, ha Remote Alarm-ot kuld a tuloldal
+zold	- eg, ha a vett jelben megtalalja a keretszinkront
+
+Reszletesebben:
+
+piros:	zold:	jelentes:
+
+-	-	nincs keretszinkron (nincs jel, vagy rossz a jel)
+-	eg	"minden rendben"
+eg	eg	a vetel OK, de a tuloldal Remote Alarm-ot kuld
+eg	-	ez nincs ertelmezve, egyelore funkcio nelkul
+
+-----------------------------------------------------------------
+
+Reszletesebb leiras a hardver beallitasi lehetosegeirol:
+
+Az altalanos,- es a protokoll-retegek beallitasi lehetosegeirol a 'comx.txt'
+fajlban leirtak SliceCOM kartyanal is ervenyesek, itt csak a hardver-specifikus
+beallitasi lehetosegek vannak osszefoglalva:
+
+Konfiguralasi interfesz a /proc/comx/ alatt:
+
+Minden timeslot-csoportnak kulon comx* interfeszt kell letrehozni mkdir-rel:
+comx0, comx1, .. stb. Itt beallithato, hogy az adott interfesz hanyadik kartya
+melyik timeslotja(i)bol alljon ossze. A Cisco-fele serial3:1 elnevezesek
+(serial3:1 = a 3. kartyaban az 1-es idoszelet-csoport) Linuxon aliasing-ot
+jelentenenek, ezert mi nem tudunk ilyen elnevezest hasznalni.
+
+Tobb kartya eseten a comx0.1, comx0.2, ... vagy slice0.1, slice0.2 nevek
+hasznalhatoak.
+
+Tobb SliceCOM kartya is lehet egy gepben, de sajat interrupt kell mindegyiknek,
+nem tud meg megosztott interruptot kezelni.
+
+Az egesz kartyat erinto beallitasok:
+
+Az ioport es irq beallitas nincs: amit a PCI BIOS kioszt a rendszernek,
+azt hasznalja a driver.
+
+
+comx0/boardnum	- hanyadik SliceCOM kartya a gepben (a 'termeszetes' PCI
+		sorrendben ertve: ahogyan a /proc/pci-ban vagy az 'lspci'
+		kimeneteben megjelenik, altalaban az alaplapi PCI meghajto
+		aramkorokhoz kozelebb eso kartyak a kisebb sorszamuak)
+
+		Default: 0 (0-tol kezdodik a szamolas)
+
+
+Bar a kovetkezoket csak egy-egy interfeszen allitjuk at, megis az egesz kartya
+mukodeset egyszerre allitjak. A megkotes hogy csak UP-ban levo interfeszen
+hasznalhatoak, azert van, mert kulonben nem vart eredmenyekre vezetne egy ilyen
+paranccsorozat:
+
+	echo 0        >boardnum
+	echo internal >clock_source
+	echo 1        >boardnum
+
+- Ez a 0-s board clock_source-at allitana at.
+
+Ezek a beallitasok megmaradnak az osszes interfesz torlesekor, de torlodnek
+a driver modul ki/betoltesekor.
+
+
+comx0/clock_source - A Tx orajelforrasa, a Cisco-val hasonlatosra keszult.
+	Hasznalata:
+
+	papaya:# echo line     >/proc/comx/comx0/clock_source
+	papaya:# echo internal >/proc/comx/comx0/clock_source
+
+	line     - A Tx orajelet a vett adatfolyambol dekodolja, igyekszik
+		igazodni hozza. Ha nem lat orajelet az inputon, akkor
+		atall a sajat orajelgeneratorara.
+	internal - A Tx orajelet a sajat orajelgeneratora szolgaltatja.
+
+	Default: line
+
+	Normal osszeallitas eseten a tavkozlesi szolgaltato eszkoze
+	(pl. HDSL modem) adja az orajelet, ezert ez a default.
+
+
+comx0/framing	- A CRC4 ki/be kapcsolasa
+
+	A CRC4: 16 PCM keretet (A PCM keret az, amibe a 32 darab 64
+	kilobites csatorna van bemultiplexalva. Nem osszetevesztendo a HDLC
+	kerettel.) 2x8 -as csoportokra osztanak, es azokhoz 4-4 bites CRC-t
+	szamolnak. Elsosorban a vonal minosegenek a monitorozasara szolgal.
+
+	papaya:~# echo crc4	>/proc/comx/comx0/framing
+	papaya:~# echo no-crc4	>/proc/comx/comx0/framing
+
+	Default a 'crc4', a MATAV vonalak altalaban igy futnak. De ha nem
+	egyforma is a beallitas a vonal ket vegen, attol a forgalom altalaban
+	at tud menni.
+
+
+comx0/linecode	- A vonali kodolas beallitasa
+
+	papaya:~# echo hdb3	>/proc/comx/comx0/linecode
+	papaya:~# echo ami	>/proc/comx/comx0/linecode
+
+	Default a 'hdb3', a MATAV vonalak igy futnak.
+	
+	(az AMI kodolas igen ritka E1-es vonalaknal). Ha ez a beallitas nem
+	egyezik a vonal ket vegen, akkor elofordulhat hogy a keretszinkron
+	osszejon, de CRC4-hibak es a vonalakon atvitt adatokban is hibak
+	keletkeznek (amit a HDLC/SyncPPP szinten CRC-hibaval jelez)
+
+
+comx0/reg	- a kartya aramkoreinek, a MUNICH (reg) es a FALC (lbireg)
+comx0/lbireg	regisztereinek kozvetlen elerese. Hasznalata:
+
+		echo >reg 0x04 0x0	- a 4-es regiszterbe 0-t ir
+		echo >reg 0x104		- printk()-val kiirja a 4-es regiszter
+					tartalmat a syslogba.
+
+		WARNING: ezek csak a fejleszteshez keszultek, sok galibat
+		lehet veluk okozni!
+
+
+comx0/loopback - A kartya G.703 jelenek a visszahurkolasara is van lehetoseg:
+
+	papaya:# echo none   >/proc/comx/comx0/loopback
+	papaya:# echo local  >/proc/comx/comx0/loopback
+	papaya:# echo remote >/proc/comx/comx0/loopback
+
+	none   - nincs visszahurkolas, normal mukodes
+	local  - a kartya a sajat maga altal adott jelet kapja vissza
+	remote - a kartya a kivulrol vett jelet adja kifele
+
+	Default: none
+
+-----------------------------------------------------------------
+
+Az interfeszhez (Cisco terminologiaban 'channel-group') kapcsolodo beallitasok:
+
+comx0/timeslots	- mely timeslotok (idoszeletek) tartoznak az adott interfeszhez.
+
+	papaya:~# cat /proc/comx/comx0/timeslots
+	1 3 4 5 6
+	papaya:~#
+
+	Egy timeslot megkeresese (hanyas interfeszbe tartozik nalunk):
+
+	papaya:~# grep ' 4' /proc/comx/comx*/timeslots
+	/proc/comx/comx0/timeslots:1 3 4 5 6
+	papaya:~#
+
+	Beallitasa:
+	papaya:~# echo '1 5 2 6 7 8' >/proc/comx/comx0/timeslots
+	
+	A timeslotok sorrendje nem szamit, '1 3 2' ugyanaz mint az '1 2 3'.
+
+	Beallitashoz az adott interfesznek DOWN-ban kell lennie
+	(ifconfig comx0 down), de ugyanannak a kartyanak a tobbi interfesze
+	uzemelhet kozben.
+
+	Beallitaskor leellenorzi, hogy az uj timeslotok nem utkoznek-e egy
+	masik interfesz timeslotjaival. Ha utkoznek, akkor nem allitja at.
+
+	Mindig 10-es szamrendszerben tortenik a timeslotok ertelmezese, nehogy
+	a 08, 09 alaku felirast rosszul ertelmezze.
+
+-----------------------------------------------------------------
+
+Az interfeszek es a kartya allapotanak lekerdezese:
+
+- A ' '-szel kezdodo sorok az eredeti kimenetet, a //-rel kezdodo sorok a
+magyarazatot jelzik.
+
+ papaya:~$ cat /proc/comx/comx1/status
+ Interface administrative status is UP, modem status is UP, protocol is UP
+ Modem status changes: 0, Transmitter status is IDLE, tbusy: 0
+ Interface load (input): 978376 / 947808 / 951024 bits/s (5s/5m/15m)
+               (output): 978376 / 947848 / 951024 bits/s (5s/5m/15m)
+ Debug flags: none
+ RX errors: len: 22, overrun: 1, crc: 0, aborts: 0
+            buffer overrun: 0, pbuffer overrun: 0
+ TX errors: underrun: 0
+ Line keepalive (value: 10) status UP [0]
+
+// Itt kezdodik a hardver-specifikus resz:
+ Controller status:
+         No alarms
+
+// Alarm: hibajelzes:
+//
+// No alarms - minden rendben
+//
+// LOS  - Loss Of Signal - nem erzekel jelet a bemeneten.
+// AIS  - Alarm Indication Signal - csak egymas utani 1-esek jonnek
+//	a bemeneten, a tuloldal igy is jelezheti hogy meghibasodott vagy
+//	nincs inicializalva.
+// AUXP - Auxiliary Pattern Indication - 01010101.. sorozat jon a bemeneten.
+// LFA  - Loss of Frame Alignment - nincs keretszinkron
+// RRA  - Receive Remote Alarm - a tuloldal el, de hibat jelez.
+// LMFA - Loss of CRC4 Multiframe Alignment - nincs CRC4-multikeret-szinkron
+// NMF  - No Multiframe alignment Found after 400 msec - ilyen alarm a no-crc4
+//	es crc4 keretezesek eseten nincs, lasd lentebb
+//
+// Egyeb lehetseges hibajelzesek:
+//
+// Transmit Line Short - a kartya ugy erzi hogy az adasi kimenete rovidre
+//	van zarva, ezert kikapcsolta az adast. (nem feltetlenul veszi eszre
+//	a kulso rovidzarat)
+
+// A veteli oldal csomagjainak lancolt listai, debug celokra:
+
+ Rx ring:
+         rafutott: 0
+         lastcheck: 50845731, jiffies: 51314281
+         base: 017b1858
+         rx_desc_ptr: 0
+         rx_desc_ptr: 017b1858
+         hw_curr_ptr: 017b1858
+         06040000 017b1868 017b1898 c016ff00
+         06040000 017b1878 017b1e9c c016ff00
+         46040000 017b1888 017b24a0 c016ff00
+         06040000 017b1858 017b2aa4 c016ff00
+
+// A kartyat hasznalo tobbi interfesz: a 0-s channel-group a comx1 interfesz,
+// es az 1,2,...,16 timeslotok tartoznak hozza:
+
+ Interfaces using this board: (channel-group, interface, timeslots)
+          0 comx1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
+          1 comx2: 17
+          2 comx3: 18
+          3 comx4: 19
+          4 comx5: 20
+          5 comx6: 21
+          6 comx7: 22
+          7 comx8: 23
+          8 comx9: 24
+          9 comx10: 25
+         10 comx11: 26
+         11 comx12: 27
+         12 comx13: 28
+         13 comx14: 29
+         14 comx15: 30
+         15 comx16: 31
+
+// Hany esemenyt kezelt le a driver egy-egy hardver-interrupt kiszolgalasanal:
+
+ Interrupt work histogram:
+ hist[ 0]:        0 hist[ 1]:        2 hist[ 2]:    18574 hist[ 3]:       79
+ hist[ 4]:       14 hist[ 5]:        1 hist[ 6]:        0 hist[ 7]:        1
+ hist[ 8]:        0 hist[ 9]:        7
+
+// Hany kikuldendo csomag volt mar a Tx-ringben amikor ujabb lett irva bele:
+
+ Tx ring histogram:
+ hist[ 0]:     2329 hist[ 1]:        0 hist[ 2]:        0 hist[ 3]:        0
+
+// Az E1-interfesz hiba-szamlaloi, az rfc2495-nek megfeleloen:
+// (kb. a Cisco routerek "show controllers e1" formatumaban: http://www.cisco.com/univercd/cc/td/doc/product/software/ios11/rbook/rinterfc.htm#xtocid25669126)
+
+Data in current interval (91 seconds elapsed):
+   9516 Line Code Violations, 65 Path Code Violations, 2 E-Bit Errors
+   0 Slip Secs, 2 Fr Loss Secs, 2 Line Err Secs, 0 Degraded Mins
+   0 Errored Secs, 0 Bursty Err Secs, 0 Severely Err Secs, 11 Unavail Secs
+Data in Interval 1 (15 minutes):
+   0 Line Code Violations, 0 Path Code Violations, 0 E-Bit Errors
+   0 Slip Secs, 0 Fr Loss Secs, 0 Line Err Secs, 0 Degraded Mins
+   0 Errored Secs, 0 Bursty Err Secs, 0 Severely Err Secs, 0 Unavail Secs
+Data in last 4 intervals (1 hour):
+   0 Line Code Violations, 0 Path Code Violations, 0 E-Bit Errors
+   0 Slip Secs, 0 Fr Loss Secs, 0 Line Err Secs, 0 Degraded Mins
+   0 Errored Secs, 0 Bursty Err Secs, 0 Severely Err Secs, 0 Unavail Secs
+Data in last 96 intervals (24 hours):
+   0 Line Code Violations, 0 Path Code Violations, 0 E-Bit Errors
+   0 Slip Secs, 0 Fr Loss Secs, 0 Line Err Secs, 0 Degraded Mins
+   0 Errored Secs, 0 Bursty Err Secs, 0 Severely Err Secs, 0 Unavail Secs
+
+-----------------------------------------------------------------
+
+Nehany kulonlegesebb beallitasi lehetoseg (idovel beepulhetnek majd a driverbe):
+Ezekkel sok galibat lehet okozni, nagyon ovatosan kell oket hasznalni!
+
+	modified CRC-4, for improved interworking of CRC-4 and non-CRC-4
+	devices: (lasd page 107 es g706 Annex B)
+		lbireg[ 0x1b ] |= 0x08
+		lbireg[ 0x1c ] |= 0xc0
+	- ilyenkor ertelmezett az NMF - 'No Multiframe alignment Found after
+	400 msec' alarm.
+
+	FALC - a vonali meghajto IC
+	local loop - a sajat adasomat halljam vissza
+	remote loop - a kivulrol jovo adast adom vissza
+
+	Egy hibakeresesre hasznalhato dolog:
+		- 1-es timeslot local loop a FALC-ban:	echo >lbireg 0x1d 0x21
+		- local loop kikapcsolasa:		echo >lbireg 0x1d 0x00
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/networking/slicecom.txt linux/Documentation/networking/slicecom.txt
--- linux.orig/Documentation/networking/slicecom.txt	Thu Jan  1 00:00:00 1970
+++ linux/Documentation/networking/slicecom.txt	Tue May 28 22:39:13 2002
@@ -0,0 +1,369 @@
+
+SliceCOM adapter user's documentation - for the 0.51 driver version
+
+Written by Bartók István <bartoki@itc.hu>
+
+English translation: Lakatos György <gyuri@itc.hu>
+Mon Dec 11 15:28:42 CET 2000
+
+Last modified: Wed Aug 29 17:25:37 CEST 2001
+
+-----------------------------------------------------------------
+
+Usage:
+
+Compiling the kernel:
+
+Code maturity level options
+	[*] Prompt for development and/or incomplete code/drivers
+
+Network device support
+	Wan interfaces
+		<M> MultiGate (COMX) synchronous
+			<M> Support for MUNICH based boards: SliceCOM, PCICOM (NEW)
+			<M> Support for HDLC and syncPPP...
+
+
+Loading the modules:
+
+modprobe comx
+
+modprobe comx-proto-ppp		# module for  Cisco-HDLC and SyncPPP protocols
+
+modprobe comx-hw-munich		# the module logs information by the kernel
+				# about the detected boards
+
+
+Configuring the board:
+
+# This interface will use the Cisco-HDLC line protocol,
+# the timeslices assigned are 1,2 (128 KiBit line speed)
+# (the first data timeslice in the G.703 frame is no. 1)
+#
+mkdir /proc/comx/comx0.1/
+echo slicecom	>/proc/comx/comx0.1/boardtype
+echo hdlc	>/proc/comx/comx0.1/protocol
+echo 1 2	>/proc/comx/comx0.1/timeslots
+
+
+# This interface uses SyncPPP line protocol, the assigned 
+# is no. 3 (64 KiBit line speed)
+#
+mkdir /proc/comx/comx0.2/
+echo slicecom	>/proc/comx/comx0.2/boardtype
+echo ppp	>/proc/comx/comx0.2/protocol
+echo 3		>/proc/comx/comx0.2/timeslots
+
+...
+
+ifconfig comx0.1 up
+ifconfig comx0.2 up
+
+-----------------------------------------------------------------
+
+The COMX interfaces use a 10 packet transmit queue by default, however WAN
+networks sometimes use bigger values (20 to 100), to utilize the line better
+by large traffic (though the line delay increases because of more packets
+join the queue).
+
+# ifconfig comx0 txqueuelen 50
+
+This option is only supported by the ifconfig command of the later 
+distributions, which came with 2.2 kernels, such as RedHat 6.1 or Debian 2.2.
+
+You can download a newer netbase packet from 
+http://www.debian.org/~rcw/2.2/netbase/ for Debian 2.1, which has a new
+ifconfig. You can get further information about using 2.2 kernel with
+Debian 2.1 from http://www.debian.org/releases/stable/running-kernel-2.2
+
+-----------------------------------------------------------------
+
+The SliceCom LEDs:
+
+red	- on, if the interface is unconfigured, or it gets Remote Alarm-s
+green	- on, if the board finds frame-sync in the received signal 	
+
+A bit more detailed:
+
+red:	green:	meaning:
+
+-	-	no frame-sync, no signal received, or signal SNAFU.
+-	on	"Everything is OK"
+on	on	Recepion is ok, but the remote end sends Remote Alarm
+on	-	The interface is unconfigured
+
+-----------------------------------------------------------------
+
+A more detailed description of the hardware setting options:
+
+The general and the protocol layer options described in the 'comx.txt' file
+apply to the SliceCom as well, I only summarize the SliceCom hardware specific
+settings below.
+
+The '/proc/comx' configuring interface:
+
+An interface directory should be created for every timeslot group with
+'mkdir', e,g: 'comx0', 'comx1' etc. The timeslots can be assigned here to the
+specific interface. The Cisco-like naming convention (serial3:1 - first
+timeslot group of the 3rd. board) can't be used here, because these mean IP
+aliasing in Linux.
+
+You can give any meaningful name to keep the configuration clear; 
+e.g: 'comx0.1', 'comx0.2', 'comx1.1', comx1.2', if you have two boards
+with two interfaces each.
+
+Settings, which apply to the board:
+
+Neither 'io' nor 'irq' settings required, the driver uses the resources
+given by the PCI BIOS.
+
+comx0/boardnum	- board number of the SliceCom in the PC (using the 'natural'
+		PCI order) as listed in '/proc/pci' or the output of the
+	 	'lspci' command, generally the slots nearer to the motherboard
+		PCI driver chips have the lower numbers.
+		
+		Default: 0 (the counting starts with 0)
+
+Though the options below are to be set on a single interface, they apply to the
+whole board. The restriction, to use them on 'UP' interfaces, is because the 
+command sequence below could lead to unpredicable results.
+
+	# echo 0        >boardnum
+	# echo internal >clock_source
+	# echo 1        >boardnum
+
+The sequence would set the clock source of board 0.
+
+These settings will persist after all the interfaces are cleared, but are
+cleared when the driver module is unloaded and loaded again.
+
+comx0/clock_source - source of the transmit clock
+	Usage:
+
+	# echo line     >/proc/comx/comx0/clock_source
+	# echo internal >/proc/comx/comx0/clock_source
+
+	line	- The Tx clock is being decoded if the input data stream,
+		if no clock seen on the input, then the board will use it's
+		own clock generator.
+
+	internal - The Tx clock is supplied by the builtin clock generator. 	
+
+	Default: line
+
+	Normally, the telecommunication company's end device (the HDSL
+	modem) provides the Tx clock, that's why 'line' is the default.
+
+comx0/framing	- Switching CRC4 off/on
+
+	CRC4: 16 PCM frames (The 32 64Kibit channels are multiplexed into a
+	PCM frame, nothing to do with HDLC frames) are divided into 2x8
+	groups, each group has a 4 bit CRC.
+
+	# echo crc4	>/proc/comx/comx0/framing
+	# echo no-crc4	>/proc/comx/comx0/framing
+
+	Default is 'crc4', the Hungarian MATAV lines behave like this. 
+	The traffic generally passes if this setting on both ends don't match.
+
+comx0/linecode	- Setting the line coding
+
+	# echo hdb3	>/proc/comx/comx0/linecode
+	# echo ami	>/proc/comx/comx0/linecode
+
+	Default a 'hdb3', MATAV lines use this.
+	
+	(AMI coding is rarely used with E1 lines). Frame sync may occur, if
+	this setting doesn't match the other end's, but CRC4 and data errors
+	will come, which will result in CRC errors on HDLC/SyncPPP level. 
+
+comx0/reg	- direct access to the board's MUNICH (reg) and FALC (lbireg)
+comx0/lbireg	circuit's registers  
+
+	# echo >reg 0x04 0x0	- write 0 to register 4
+	# echo >reg 0x104	- write the contents of register 4 with
+				printk() to syslog
+
+WARNING! These are only for development purposes, messing with this will
+	result much trouble!
+
+comx0/loopback - Places a loop to the board's G.703 signals
+
+	# echo none   >/proc/comx/comx0/loopback
+	# echo local  >/proc/comx/comx0/loopback
+	# echo remote >/proc/comx/comx0/loopback
+
+	none   - normal operation, no loop
+	local  - the board receives it's own output
+	remote - the board sends the received data to the remote side
+
+	Default: none
+
+-----------------------------------------------------------------
+
+Interface (channel group in Cisco terms) settings: 
+
+comx0/timeslots	- which timeslots belong to the given interface
+
+	Setting:
+
+	# echo '1 5 2 6 7 8' >/proc/comx/comx0/timeslots
+
+	# cat /proc/comx/comx0/timeslots
+	1 2 5 6 7 8 
+	#
+
+	Finding a timeslot: 
+
+	# grep ' 4' /proc/comx/comx*/timeslots
+	/proc/comx/comx0/timeslots:1 3 4 5 6
+	#
+
+	The timeslots can be in any order, '1 2 3' is the same as '1 3 2'.
+
+	The interface has to be DOWN during the setting ('ifconfig comx0
+	down'), but the other interfaces could operate normally.
+
+	The driver checks if the assigned timeslots are vacant, if not, then
+	the setting won't be applied.
+
+	The timeslot values are treated as decimal numbers, not to misunderstand
+	values of 08, 09 form.
+
+-----------------------------------------------------------------
+
+Checking the interface and board status:
+
+- Lines beginning with ' ' (space) belong to the original output, the lines
+which begin with '//' are the comments.
+
+ papaya:~$ cat /proc/comx/comx1/status
+ Interface administrative status is UP, modem status is UP, protocol is UP
+ Modem status changes: 0, Transmitter status is IDLE, tbusy: 0
+ Interface load (input): 978376 / 947808 / 951024 bits/s (5s/5m/15m)
+               (output): 978376 / 947848 / 951024 bits/s (5s/5m/15m)
+ Debug flags: none
+ RX errors: len: 22, overrun: 1, crc: 0, aborts: 0
+            buffer overrun: 0, pbuffer overrun: 0
+ TX errors: underrun: 0
+ Line keepalive (value: 10) status UP [0]
+
+// The hardware specific part starts here:
+ Controller status:
+         No alarms
+
+// Alarm: 
+//
+// No alarms - Everything OK
+//
+// LOS  - Loss Of Signal - No signal sensed on the input
+// AIS  - Alarm Indication Signal - The remot side sends '11111111'-s, 
+//	it tells, that there's an error condition, or it's not
+//	initialised.
+// AUXP - Auxiliary Pattern Indication - 01010101.. received.
+// LFA  - Loss of Frame Alignment - no frame sync received.
+// RRA  - Receive Remote Alarm - the remote end's OK, but singnals error cond.
+// LMFA - Loss of CRC4 Multiframe Alignment - no CRC4 multiframe sync.
+// NMF  - No Multiframe alignment Found after 400 msec - no such alarm using
+//	no-crc4 or crc4 framing, see below.
+//
+// Other possible error messages:
+//
+// Transmit Line Short - the board felt, that it's output is short-circuited,
+// 	so it switched the transmission off. (The board can't definitely tell,
+//	that it's output is short-circuited.)
+
+// Chained list of the received packets, for debug purposes:
+
+ Rx ring:
+         rafutott: 0
+         lastcheck: 50845731, jiffies: 51314281
+         base: 017b1858
+         rx_desc_ptr: 0
+         rx_desc_ptr: 017b1858
+         hw_curr_ptr: 017b1858
+         06040000 017b1868 017b1898 c016ff00
+         06040000 017b1878 017b1e9c c016ff00
+         46040000 017b1888 017b24a0 c016ff00
+         06040000 017b1858 017b2aa4 c016ff00
+
+// All the interfaces using the board: comx1, using the 1,2,...16 timeslots,
+// comx2, using timeslot 17, etc.
+
+ Interfaces using this board: (channel-group, interface, timeslots)
+          0 comx1: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
+          1 comx2: 17
+          2 comx3: 18
+          3 comx4: 19
+          4 comx5: 20
+          5 comx6: 21
+          6 comx7: 22
+          7 comx8: 23
+          8 comx9: 24
+          9 comx10: 25
+         10 comx11: 26
+         11 comx12: 27
+         12 comx13: 28
+         13 comx14: 29
+         14 comx15: 30
+         15 comx16: 31
+
+// The number of events handled by the driver during an interrupt cycle:
+
+ Interrupt work histogram:
+ hist[ 0]:        0 hist[ 1]:        2 hist[ 2]:    18574 hist[ 3]:       79
+ hist[ 4]:       14 hist[ 5]:        1 hist[ 6]:        0 hist[ 7]:        1
+ hist[ 8]:        0 hist[ 9]:        7
+
+// The number of packets to send in the Tx ring, when a new one arrived:
+
+ Tx ring histogram:
+ hist[ 0]:     2329 hist[ 1]:        0 hist[ 2]:        0 hist[ 3]:        0
+
+// The error counters of the E1 interface, according to the RFC2495,
+// (similar to the Cisco "show controllers e1" command's output:
+// http://www.cisco.com/univercd/cc/td/doc/product/software/ios11/rbook/rinterfc.htm#xtocid25669126)
+
+Data in current interval (91 seconds elapsed):
+   9516 Line Code Violations, 65 Path Code Violations, 2 E-Bit Errors
+   0 Slip Secs, 2 Fr Loss Secs, 2 Line Err Secs, 0 Degraded Mins
+   0 Errored Secs, 0 Bursty Err Secs, 0 Severely Err Secs, 11 Unavail Secs
+Data in Interval 1 (15 minutes):
+   0 Line Code Violations, 0 Path Code Violations, 0 E-Bit Errors
+   0 Slip Secs, 0 Fr Loss Secs, 0 Line Err Secs, 0 Degraded Mins
+   0 Errored Secs, 0 Bursty Err Secs, 0 Severely Err Secs, 0 Unavail Secs
+Data in last 4 intervals (1 hour):
+   0 Line Code Violations, 0 Path Code Violations, 0 E-Bit Errors
+   0 Slip Secs, 0 Fr Loss Secs, 0 Line Err Secs, 0 Degraded Mins
+   0 Errored Secs, 0 Bursty Err Secs, 0 Severely Err Secs, 0 Unavail Secs
+Data in last 96 intervals (24 hours):
+   0 Line Code Violations, 0 Path Code Violations, 0 E-Bit Errors
+   0 Slip Secs, 0 Fr Loss Secs, 0 Line Err Secs, 0 Degraded Mins
+   0 Errored Secs, 0 Bursty Err Secs, 0 Severely Err Secs, 0 Unavail Secs
+
+-----------------------------------------------------------------
+
+Some unique options, (may get into the driver later):
+Treat them very carefully, these can cause much trouble!
+
+	modified CRC-4, for improved interworking of CRC-4 and non-CRC-4
+	devices: (see page 107 and g706 Annex B)
+		lbireg[ 0x1b ] |= 0x08
+		lbireg[ 0x1c ] |= 0xc0
+
+	- The NMF - 'No Multiframe alignment Found after 400 msec' alarm 
+	comes into account.
+
+	FALC - the line driver chip.
+	local loop - I hear my transmission back.
+	remote loop - I echo the remote transmission back.
+
+	Something useful for finding errors:
+	
+		- local loop for timeslot 1 in the FALC chip:
+
+	# echo >lbireg 0x1d 0x21
+
+		- Swithing the loop off:
+
+	# echo >lbireg 0x1d 0x00
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/networking/vortex.txt linux/Documentation/networking/vortex.txt
--- linux.orig/Documentation/networking/vortex.txt	Sun Aug 12 19:27:36 2001
+++ linux/Documentation/networking/vortex.txt	Tue May 28 22:39:19 2002
@@ -117,6 +117,12 @@
   will force full-duplex 100base-TX, rather than allowing the usual
   autonegotiation.
 
+global_options=N
+
+  Sets the `options' parameter for all 3c59x NICs in the machine. 
+  Entries in the `options' array above will override any setting of
+  this.
+
 full_duplex=N1,N2,N3...
 
   Similar to bit 9 of 'options'.  Forces the corresponding card into
@@ -126,6 +132,11 @@
   In fact, please don't use this at all! You're better off getting
   autonegotiation working properly.
 
+global_full_duplex=N1
+
+  Sets full duplex mode for all 3c59x NICs in the machine.  Entries
+  in the `full_duplex' array above will override any setting of this.
+
 flow_ctrl=N1,N2,N3...
 
   Use 802.3x MAC-layer flow control.  The 3com cards only support the
@@ -211,6 +222,12 @@
   Becker's `ether-wake' application may be used to wake suspended
   machines.
 
+  Also enables the NIC's power management support.
+
+global_enable_wol=N
+
+  Sets enable_wol mode for all 3c59x NICs in the machine.  Entries in
+  the `enable_wol' array above will override any setting of this.
 
 Media selection
 ---------------
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/pci.txt linux/Documentation/pci.txt
--- linux.orig/Documentation/pci.txt	Fri Dec 21 17:41:53 2001
+++ linux/Documentation/pci.txt	Tue May 28 22:39:27 2002
@@ -156,6 +156,11 @@
 which enables the bus master bit in PCI_COMMAND register and also fixes
 the latency timer value if it's set to something bogus by the BIOS.
 
+   If you want to use the PCI Memory-Write-Invalidate transaction,
+call pci_set_mwi().  This enables bit PCI_COMMAND bit for Mem-Wr-Inval
+and also ensures that the cache line size register is set correctly.
+Make sure to check the return value of pci_set_mwi(), not all architectures
+may support Memory-Write-Invalidate.
 
 4. How to access PCI config space
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -202,6 +207,8 @@
 pci_resource_len()		Returns the byte length of a PCI region
 pci_set_drvdata()		Set private driver data pointer for a pci_dev
 pci_get_drvdata()		Return private driver data pointer for a pci_dev
+pci_set_mwi()			Enable Memory-Write-Invalidate transactions.
+pci_clear_mwi()			Disable Memory-Write-Invalidate transactions.
 
 
 7. Miscellaneous hints
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/power/pci.txt linux/Documentation/power/pci.txt
--- linux.orig/Documentation/power/pci.txt	Thu Jun 28 21:58:05 2001
+++ linux/Documentation/power/pci.txt	Tue May 28 22:39:21 2002
@@ -63,7 +63,7 @@
 callbacks. This currently takes place only during APM state transitions.
 
 Upon going to sleep, the PCI subsystem walks its device tree twice. Both times, it does
-a depth first walk of the device tree. The first walk saves  each of the device's state 
+a depth first walk of the device tree. The first walk saves each of the device's state 
 and checks for devices that will prevent the system from entering a global power state. 
 The next walk then places the devices in a low power state.
 
@@ -104,7 +104,7 @@
 -----------------
 
 Usage:
-	pci_restore_state(dev,buffer);
+	pci_restore_state(dev, buffer);
 
 Description:
 	Restore previously saved config space. (First 64 bytes only);
@@ -117,7 +117,7 @@
 -------------------
 
 Usage:
-	pci_set_power_state(dev,state);
+	pci_set_power_state(dev, state);
 
 Description:
 	Transition device to low power state using PCI PM Capabilities registers.
@@ -132,7 +132,7 @@
 ---------------
 
 Usage:
-	pci_enable_wake(dev,state,enable);
+	pci_enable_wake(dev, state, enable);
 
 Description:
 	Enable device to generate PME# during low power state using PCI PM 
@@ -155,7 +155,7 @@
 struct pci_driver:
 
         int  (*save_state) (struct pci_dev *dev, u32 state);
-        int  (*suspend)(struct pci_dev *dev, u32 state);
+        int  (*suspend) (struct pci_dev *dev, u32 state);
         int  (*resume) (struct pci_dev *dev);
         int  (*enable_wake) (struct pci_dev *dev, u32 state, int enable);
 
@@ -178,7 +178,7 @@
 
 The driver can also interpret this function as a notification that it may be entering
 a sleep state in the near future. If it knows that the device cannot enter the 
-requested state, either because of lack of support for it, or because the devices is 
+requested state, either because of lack of support for it, or because the device is 
 middle of some critical operation, then it should fail.
 
 This function should not be used to set any state in the device or the driver because
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/sonypi.txt linux/Documentation/sonypi.txt
--- linux.orig/Documentation/sonypi.txt	Mon Feb 25 19:37:51 2002
+++ linux/Documentation/sonypi.txt	Tue May 28 22:39:13 2002
@@ -36,14 +36,14 @@
 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:
+Driver options:
 ---------------
 
 Several options can be passed to the sonypi driver, either by adding them
 to /etc/modules.conf file, when the driver is compiled as a module or by
 adding the following to the kernel command line (in your bootloader):
 
-	sonypi=minor[[[[,camera],fnkeyinit],verbose],compat]
+	sonypi=minor[,verbose[,fnkeyinit[,camera[,compat[,nojogdial]]]]]
 
 where:
 
@@ -70,6 +70,9 @@
 			events. If the driver worked for you in the past
 			(prior to version 1.5) and does not work anymore,
 			add this option and report to the author.
+
+	nojogdial:	gives more accurate PKEY events on those Vaio models
+			which don't have a jogdial (like the FX series).
 
 Module use:
 -----------
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/sound/OPL3-SA2 linux/Documentation/sound/OPL3-SA2
--- linux.orig/Documentation/sound/OPL3-SA2	Wed Jul 18 14:14:01 2001
+++ linux/Documentation/sound/OPL3-SA2	Tue May 28 22:39:16 2002
@@ -65,7 +65,7 @@
 ------------
 
 In previous kernels (2.2.x), some configuration was required to
-get the driver to talk to the card.  Being the new millenium and
+get the driver to talk to the card.  Being the new millennium and
 all, the 2.4.x kernels now support auto-configuration if ISA PnP
 support is configured in.  Theoretically, the driver even supports
 having more than one card in this case.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/sound/README.OSS linux/Documentation/sound/README.OSS
--- linux.orig/Documentation/sound/README.OSS	Tue Jun 12 17:56:11 2001
+++ linux/Documentation/sound/README.OSS	Tue May 28 22:39:14 2002
@@ -542,7 +542,7 @@
 
 	SoftOSS keeps the samples loaded on the system's RAM so much RAM is
 	required. SoftOSS should never be used on machines with less than 16 MB
-	of RAM since this is potentially dangerous (you may accidently run out
+	of RAM since this is potentially dangerous (you may accidentally run out
 	of memory which probably crashes the machine). 
 
 	SoftOSS implements the wave table API originally designed for GUS. For
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/sound/rme96xx linux/Documentation/sound/rme96xx
--- linux.orig/Documentation/sound/rme96xx	Thu Jan  1 00:00:00 1970
+++ linux/Documentation/sound/rme96xx	Tue May 28 22:39:16 2002
@@ -0,0 +1,767 @@
+Beta release of the rme96xx (driver for RME 96XX cards like the 
+"Hammerfall" and the "Hammerfall light") 
+
+Important: The driver module has to be installed on a freshly rebooted system, 
+otherwise the driver might not be able to acquire its buffers.
+
+features:
+
+ - OSS programming interface (i.e. runs with standard OSS soundsoftware) 
+ - OSS/Multichannel interface (OSS multichannel is done by just aquiring
+   more than 2 channels). The driver does not use more than one device 
+   ( yet .. this feature may be implemented later ) 
+ - more than one RME card supported
+
+The driver uses a specific multichannel interface, which I will document
+when the driver gets stable. (take a look at the defines in rme96xx.h,
+which adds blocked multichannel formats i.e instead of 
+lrlrlrlr --> llllrrrr  etc.
+
+Use the "rmectrl" programm to look at the status of the card .. 
+or use xrmectrl, a GUI interface for the ctrl program.
+
+What you can do with the rmectrl program is to set the stereo device for
+OSS emulation (e.g. if you use SPDIF out).
+
+You do:
+
+./ctrl offset 24 24
+
+which makes the stereo device use channels 25 and 26.
+
+Guenter Geiger <geiger@epy.co.at> 
+               
+copy the first part of the attached source code into rmectrl.c
+and the  second part into xrmectrl (or get the program from
+http://gige.xdv.org/pages/soft/pages/rme)
+
+to compile: gcc -o rmectrl rmectrl.c
+------------------------------ snip ------------------------------------
+ 
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <linux/soundcard.h>
+#include <math.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include "rme96xx.h"
+
+/*
+  remctrl.c
+  (C) 2000 Guenter Geiger <geiger@debian.org>
+  HP20020201 - Heiko Purnhagen <purnhage@tnt.uni-hannover.de>
+*/
+
+/* # define DEVICE_NAME "/dev/mixer" */
+# define DEVICE_NAME "/dev/mixer1"
+
+
+void usage(void)
+{
+     fprintf(stderr,"usage: rmectrl [/dev/mixer<n>] [command [options]]\n\n");
+     fprintf(stderr,"where command is one of:\n");
+     fprintf(stderr,"  help                       show this help\n");
+     fprintf(stderr,"  status                     show status bits\n");
+     fprintf(stderr,"  control                    show control bits\n");
+     fprintf(stderr,"  mix                        show mixer/offset status\n");
+     fprintf(stderr,"  master <n>                 set sync master\n");
+     fprintf(stderr,"  pro <n>                    set spdif out pro\n");
+     fprintf(stderr,"  emphasis <n>               set spdif out emphasis\n");
+     fprintf(stderr,"  dolby <n>                  set spdif out no audio\n");
+     fprintf(stderr,"  optout <n>                 set spdif out optical\n");
+     fprintf(stderr,"  wordclock <n>              set sync wordclock\n");
+     fprintf(stderr,"  spdifin <n>                set spdif in (0=optical,1=coax,2=intern)\n");
+     fprintf(stderr,"  syncref <n>                set sync source (0=ADAT1,1=ADAT2,2=ADAT3,3=SPDIF)\n");
+     fprintf(stderr,"  adat1cd <n>                set ADAT1 on internal CD\n");
+     fprintf(stderr,"  offset <devnr> <in> <out>  set dev (0..3) offset (0..25)\n");
+     exit(-1);
+}
+
+
+int main(int argc, char* argv[])
+{
+     int cards;
+     int ret;
+     int i;
+     double ft;
+     int fd, fdwr;
+     int param,orig;
+     rme_status_t stat;
+     rme_ctrl_t ctrl;
+     char *device;
+     int argidx;
+
+     if (argc < 2)
+	  usage();
+
+     if (*argv[1]=='/') {
+	  device = argv[1];
+	  argidx = 2;
+     }
+     else {
+	  device = DEVICE_NAME;
+	  argidx = 1;
+     }
+
+     fprintf(stdout,"mixer device %s\n",device);
+     if ((fd = open(device,O_RDONLY)) < 0) {
+	  fprintf(stdout,"opening device failed\n");
+	  exit(-1);
+     }
+
+     if ((fdwr = open(device,O_WRONLY)) < 0) {
+	  fprintf(stdout,"opening device failed\n");
+	  exit(-1);
+     }
+
+     if (argc < argidx+1)
+	  usage();
+	  
+     if (!strcmp(argv[argidx],"help")) 
+        usage();
+     if (!strcmp(argv[argidx],"-h")) 
+        usage();
+     if (!strcmp(argv[argidx],"--help")) 
+        usage();
+
+     if (!strcmp(argv[argidx],"status")) {
+	  ioctl(fd,SOUND_MIXER_PRIVATE2,&stat);
+	  fprintf(stdout,"stat.irq %d\n",stat.irq);
+	  fprintf(stdout,"stat.lockmask %d\n",stat.lockmask);
+	  fprintf(stdout,"stat.sr48 %d\n",stat.sr48);
+	  fprintf(stdout,"stat.wclock %d\n",stat.wclock);
+	  fprintf(stdout,"stat.bufpoint %d\n",stat.bufpoint);
+	  fprintf(stdout,"stat.syncmask %d\n",stat.syncmask);
+	  fprintf(stdout,"stat.doublespeed %d\n",stat.doublespeed);
+	  fprintf(stdout,"stat.tc_busy %d\n",stat.tc_busy);
+	  fprintf(stdout,"stat.tc_out %d\n",stat.tc_out);
+	  fprintf(stdout,"stat.crystalrate %d (0=64k 3=96k 4=88.2k 5=48k 6=44.1k 7=32k)\n",stat.crystalrate);
+	  fprintf(stdout,"stat.spdif_error %d\n",stat.spdif_error);
+	  fprintf(stdout,"stat.bufid %d\n",stat.bufid);
+	  fprintf(stdout,"stat.tc_valid %d\n",stat.tc_valid);
+	  exit (0);
+     }
+	 
+     if (!strcmp(argv[argidx],"control")) {
+	  ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
+	  fprintf(stdout,"ctrl.start %d\n",ctrl.start);
+	  fprintf(stdout,"ctrl.latency %d (0=64 .. 7=8192)\n",ctrl.latency);
+	  fprintf(stdout,"ctrl.master %d\n",ctrl.master);
+	  fprintf(stdout,"ctrl.ie %d\n",ctrl.ie);
+	  fprintf(stdout,"ctrl.sr48 %d\n",ctrl.sr48);
+	  fprintf(stdout,"ctrl.spare %d\n",ctrl.spare);
+	  fprintf(stdout,"ctrl.doublespeed %d\n",ctrl.doublespeed);
+	  fprintf(stdout,"ctrl.pro %d\n",ctrl.pro);
+	  fprintf(stdout,"ctrl.emphasis %d\n",ctrl.emphasis);
+	  fprintf(stdout,"ctrl.dolby %d\n",ctrl.dolby);
+	  fprintf(stdout,"ctrl.opt_out %d\n",ctrl.opt_out);
+	  fprintf(stdout,"ctrl.wordclock %d\n",ctrl.wordclock);
+	  fprintf(stdout,"ctrl.spdif_in %d (0=optical,1=coax,2=intern)\n",ctrl.spdif_in);
+	  fprintf(stdout,"ctrl.sync_ref %d (0=ADAT1,1=ADAT2,2=ADAT3,3=SPDIF)\n",ctrl.sync_ref);
+	  fprintf(stdout,"ctrl.spdif_reset %d\n",ctrl.spdif_reset);
+	  fprintf(stdout,"ctrl.spdif_select %d\n",ctrl.spdif_select);
+	  fprintf(stdout,"ctrl.spdif_clock %d\n",ctrl.spdif_clock);
+	  fprintf(stdout,"ctrl.spdif_write %d\n",ctrl.spdif_write);
+	  fprintf(stdout,"ctrl.adat1_cd %d\n",ctrl.adat1_cd);
+	  exit (0);
+     }
+     
+     if (!strcmp(argv[argidx],"mix")) {
+	  rme_mixer mix;
+	  int i;
+	  
+	  for (i=0; i<4; i++) {
+	       mix.devnr = i;
+	       ioctl(fd,SOUND_MIXER_PRIVATE1,&mix);
+	       if (mix.devnr == i) {
+		    fprintf(stdout,"devnr %d\n",mix.devnr);
+		    fprintf(stdout,"mix.i_offset %2d (0-25)\n",mix.i_offset);
+		    fprintf(stdout,"mix.o_offset %2d (0-25)\n",mix.o_offset);
+	       }
+	  }
+	  exit (0);
+     }
+
+/* the control flags */
+
+     if (argc < argidx+2)
+	  usage();
+	  
+     if (!strcmp(argv[argidx],"master")) {
+	  int val = atoi(argv[argidx+1]);
+	  ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
+	  printf("master = %d\n",val);
+	  ctrl.master = val;
+	  ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
+	  exit (0);
+     }
+
+     if (!strcmp(argv[argidx],"pro")) {
+	  int val = atoi(argv[argidx+1]);
+	  ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
+	  printf("pro = %d\n",val);
+	  ctrl.pro = val;
+	  ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
+	  exit (0);
+     }
+
+     if (!strcmp(argv[argidx],"emphasis")) {
+	  int val = atoi(argv[argidx+1]);
+	  ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
+	  printf("emphasis = %d\n",val);
+	  ctrl.emphasis = val;
+	  ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
+	  exit (0);
+     }
+
+     if (!strcmp(argv[argidx],"dolby")) {
+	  int val = atoi(argv[argidx+1]);
+	  ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
+	  printf("dolby = %d\n",val);
+	  ctrl.dolby = val;
+	  ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
+	  exit (0);
+     }
+
+     if (!strcmp(argv[argidx],"optout")) {
+	  int val = atoi(argv[argidx+1]);
+	  ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
+	  printf("optout = %d\n",val);
+	  ctrl.opt_out = val;
+	  ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
+	  exit (0);
+     }
+
+     if (!strcmp(argv[argidx],"wordclock")) {
+	  int val = atoi(argv[argidx+1]);
+	  ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
+	  printf("wordclock = %d\n",val);
+	  ctrl.wordclock = val;
+	  ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
+	  exit (0);
+     }
+
+     if (!strcmp(argv[argidx],"spdifin")) {
+	  int val = atoi(argv[argidx+1]);
+	  ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
+	  printf("spdifin = %d\n",val);
+	  ctrl.spdif_in = val;
+	  ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
+	  exit (0);
+     }
+
+     if (!strcmp(argv[argidx],"syncref")) {
+	  int val = atoi(argv[argidx+1]);
+	  ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
+	  printf("syncref = %d\n",val);
+	  ctrl.sync_ref = val;
+	  ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
+	  exit (0);
+     }
+ 
+     if (!strcmp(argv[argidx],"adat1cd")) {
+	  int val = atoi(argv[argidx+1]);
+	  ioctl(fd,SOUND_MIXER_PRIVATE3,&ctrl);
+	  printf("adat1cd = %d\n",val);
+	  ctrl.adat1_cd = val;
+	  ioctl(fdwr,SOUND_MIXER_PRIVATE3,&ctrl);
+	  exit (0);
+     }
+ 
+/* setting offset */
+
+     if (argc < argidx+4)
+	  usage();
+	  
+     if (!strcmp(argv[argidx],"offset")) {
+	  rme_mixer mix;
+
+	  mix.devnr = atoi(argv[argidx+1]);
+	  
+	  mix.i_offset = atoi(argv[argidx+2]);
+	  mix.o_offset = atoi(argv[argidx+3]);
+	  ioctl(fdwr,SOUND_MIXER_PRIVATE1,&mix);
+	  fprintf(stdout,"devnr %d\n",mix.devnr);
+	  fprintf(stdout,"mix.i_offset to %d\n",mix.i_offset);
+	  fprintf(stdout,"mix.o_offset to %d\n",mix.o_offset);
+	  exit (0);
+     }	 
+
+     usage();
+     exit (0); /* to avoid warning */
+}
+
+
+---------------------------- <snip> --------------------------------
+#!/usr/bin/wish
+
+# xrmectrl
+# (C) 2000 Guenter Geiger <geiger@debian.org>
+# HP20020201 - Heiko Purnhagen <purnhage@tnt.uni-hannover.de>
+
+#set defaults "-relief ridged"
+set CTRLPROG "./rmectrl"
+if {$argc} {
+    set CTRLPROG "$CTRLPROG $argv"
+}
+puts "CTRLPROG $CTRLPROG"
+
+frame .butts
+button .butts.exit -text "Exit" -command "exit" -relief ridge
+#button .butts.state -text "State" -command "get_all" 
+
+pack .butts.exit -side left 
+pack .butts -side bottom 
+
+
+#
+# STATUS 
+#
+
+frame .status
+
+# Sampling Rate
+
+frame .status.sr
+label .status.sr.text -text "Sampling Rate" -justify left
+radiobutton .status.sr.441 -selectcolor red -text "44.1 kHz" -width 10 -anchor nw -variable srate -value 44100 -font times
+radiobutton .status.sr.480 -selectcolor red -text "48 kHz" -width 10 -anchor nw -variable srate -value 48000 -font times
+radiobutton .status.sr.882 -selectcolor red -text "88.2 kHz" -width 10 -anchor nw -variable srate -value 88200 -font times
+radiobutton .status.sr.960 -selectcolor red -text "96 kHz" -width 10 -anchor nw  -variable srate -value 96000 -font times
+
+pack .status.sr.text .status.sr.441 .status.sr.480 .status.sr.882 .status.sr.960 -side top -padx 3
+
+# Lock
+
+frame .status.lock
+label .status.lock.text -text "Lock" -justify left
+checkbutton .status.lock.adat1 -selectcolor red -text "ADAT1" -anchor nw -width 10 -variable adatlock1 -font times
+checkbutton .status.lock.adat2 -selectcolor red -text "ADAT2" -anchor nw -width 10 -variable adatlock2 -font times
+checkbutton .status.lock.adat3 -selectcolor red -text "ADAT3" -anchor nw -width 10 -variable adatlock3 -font times
+
+pack .status.lock.text .status.lock.adat1 .status.lock.adat2 .status.lock.adat3 -side top -padx 3 
+
+# Sync
+
+frame .status.sync
+label .status.sync.text -text "Sync" -justify left
+checkbutton .status.sync.adat1 -selectcolor red -text "ADAT1" -anchor nw -width 10 -variable adatsync1 -font times
+checkbutton .status.sync.adat2 -selectcolor red -text "ADAT2" -anchor nw -width 10 -variable adatsync2 -font times
+checkbutton .status.sync.adat3 -selectcolor red -text "ADAT3" -anchor nw -width 10 -variable adatsync3 -font times
+
+pack .status.sync.text .status.sync.adat1 .status.sync.adat2 .status.sync.adat3 -side top -padx 3 
+
+# Timecode
+
+frame .status.tc
+label .status.tc.text -text "Timecode" -justify left
+checkbutton .status.tc.busy -selectcolor red -text "busy" -anchor nw -width 10 -variable tcbusy -font times
+checkbutton .status.tc.out -selectcolor red -text "out" -anchor nw -width 10 -variable tcout -font times
+checkbutton .status.tc.valid -selectcolor red -text "valid" -anchor nw -width 10 -variable tcvalid -font times
+
+pack .status.tc.text .status.tc.busy .status.tc.out .status.tc.valid -side top -padx 3 
+
+# SPDIF In
+
+frame .status.spdif
+label .status.spdif.text -text "SPDIF In" -justify left
+label .status.spdif.sr -text "--.- kHz" -anchor n -width 10 -font times
+checkbutton .status.spdif.error -selectcolor red -text "Input Lock" -anchor nw -width 10 -variable spdiferr -font times
+
+pack .status.spdif.text .status.spdif.sr .status.spdif.error -side top -padx 3 
+
+pack .status.sr .status.lock .status.sync .status.tc .status.spdif -side left -fill x -anchor n -expand 1
+
+
+#
+# CONTROL 
+#
+
+proc setprof {} {
+    global CTRLPROG
+    global spprof
+    exec $CTRLPROG pro $spprof
+}
+
+proc setemph {} {
+    global CTRLPROG
+    global spemph
+    exec $CTRLPROG emphasis $spemph
+}
+
+proc setnoaud {} {
+    global CTRLPROG
+    global spnoaud
+    exec $CTRLPROG dolby $spnoaud
+}
+
+proc setoptical {} {
+    global CTRLPROG
+    global spoptical
+    exec $CTRLPROG optout $spoptical
+}
+
+proc setspdifin {} {
+    global CTRLPROG
+    global spdifin
+    exec $CTRLPROG spdifin [expr $spdifin - 1]
+}
+
+proc setsyncsource {} {
+    global CTRLPROG
+    global syncsource
+    exec $CTRLPROG syncref [expr $syncsource -1]
+}
+
+
+proc setmaster {} {
+    global CTRLPROG
+    global master
+    exec $CTRLPROG master $master
+}
+
+proc setwordclock {} {
+    global CTRLPROG
+    global wordclock
+    exec $CTRLPROG wordclock $wordclock
+}
+
+proc setadat1cd {} {
+    global CTRLPROG
+    global adat1cd
+    exec $CTRLPROG adat1cd $adat1cd
+}
+
+
+frame .control
+
+# SPDIF In & SPDIF Out
+
+
+frame .control.spdif
+
+frame .control.spdif.in
+label .control.spdif.in.text -text "SPDIF In" -justify left
+radiobutton .control.spdif.in.input1 -text "Optical" -anchor nw -width 13 -variable spdifin -value 1 -command setspdifin -selectcolor blue -font times
+radiobutton .control.spdif.in.input2 -text "Coaxial" -anchor nw -width 13 -variable spdifin -value 2 -command setspdifin -selectcolor blue -font times
+radiobutton .control.spdif.in.input3 -text "Intern " -anchor nw -width 13 -variable spdifin -command setspdifin -value 3 -selectcolor blue -font times
+
+checkbutton .control.spdif.in.adat1cd -text "ADAT1 Intern" -anchor nw -width 13 -variable adat1cd -command setadat1cd -selectcolor blue -font times
+
+pack .control.spdif.in.text .control.spdif.in.input1 .control.spdif.in.input2 .control.spdif.in.input3 .control.spdif.in.adat1cd
+
+label .control.spdif.space
+
+frame .control.spdif.out
+label .control.spdif.out.text -text "SPDIF Out" -justify left
+checkbutton .control.spdif.out.pro -text "Professional" -anchor nw -width 13 -variable spprof -command setprof -selectcolor blue -font times
+checkbutton .control.spdif.out.emphasis -text "Emphasis" -anchor nw -width 13 -variable spemph -command setemph -selectcolor blue -font times
+checkbutton .control.spdif.out.dolby -text "NoAudio" -anchor nw -width 13 -variable spnoaud -command setnoaud -selectcolor blue -font times
+checkbutton .control.spdif.out.optout -text "Optical Out" -anchor nw -width 13 -variable spoptical -command setoptical -selectcolor blue -font times
+
+pack .control.spdif.out.optout .control.spdif.out.dolby .control.spdif.out.emphasis .control.spdif.out.pro .control.spdif.out.text -side bottom
+
+pack .control.spdif.in .control.spdif.space .control.spdif.out -side top -fill y -padx 3 -expand 1
+
+# Sync Mode & Sync Source
+
+frame .control.sync
+frame .control.sync.mode
+label .control.sync.mode.text -text "Sync Mode" -justify left
+checkbutton .control.sync.mode.master -text "Master" -anchor nw -width 13 -variable master -command setmaster -selectcolor blue -font times
+checkbutton .control.sync.mode.wc -text "Wordclock" -anchor nw -width 13 -variable wordclock -command setwordclock -selectcolor blue -font times
+
+pack .control.sync.mode.text .control.sync.mode.master .control.sync.mode.wc
+
+label .control.sync.space
+
+frame .control.sync.src
+label .control.sync.src.text -text "Sync Source" -justify left
+radiobutton .control.sync.src.input1 -text "ADAT1" -anchor nw -width 13 -variable syncsource -value 1 -command setsyncsource -selectcolor blue -font times
+radiobutton .control.sync.src.input2 -text "ADAT2" -anchor nw -width 13 -variable syncsource -value 2 -command setsyncsource -selectcolor blue -font times
+radiobutton .control.sync.src.input3 -text "ADAT3" -anchor nw -width 13 -variable syncsource -command setsyncsource -value 3 -selectcolor blue -font times
+radiobutton .control.sync.src.input4 -text "SPDIF" -anchor nw -width 13 -variable syncsource -command setsyncsource -value 4 -selectcolor blue -font times
+
+pack .control.sync.src.input4 .control.sync.src.input3 .control.sync.src.input2 .control.sync.src.input1 .control.sync.src.text -side bottom
+
+pack .control.sync.mode .control.sync.space .control.sync.src -side top -fill y -padx 3 -expand 1
+
+label .control.space -text "" -width 10
+
+# Buffer Size
+
+frame .control.buf
+label .control.buf.text -text "Buffer Size (Latency)" -justify left
+radiobutton .control.buf.b1 -selectcolor red -text "64 (1.5 ms)" -width 13 -anchor nw -variable ssrate -value 1 -font times
+radiobutton .control.buf.b2 -selectcolor red -text "128 (3 ms)" -width 13 -anchor nw -variable ssrate -value 2 -font times
+radiobutton .control.buf.b3 -selectcolor red -text "256 (6 ms)" -width 13 -anchor nw -variable ssrate -value 3 -font times
+radiobutton .control.buf.b4 -selectcolor red -text "512 (12 ms)" -width 13 -anchor nw -variable ssrate -value 4 -font times
+radiobutton .control.buf.b5 -selectcolor red -text "1024 (23 ms)" -width 13 -anchor nw -variable ssrate -value 5 -font times
+radiobutton .control.buf.b6 -selectcolor red -text "2048 (46 ms)" -width 13 -anchor nw -variable ssrate -value 6 -font times
+radiobutton .control.buf.b7 -selectcolor red -text "4096 (93 ms)" -width 13 -anchor nw -variable ssrate -value 7 -font times
+radiobutton .control.buf.b8 -selectcolor red -text "8192 (186 ms)" -width 13 -anchor nw -variable ssrate -value 8 -font times
+
+pack .control.buf.text .control.buf.b1 .control.buf.b2 .control.buf.b3 .control.buf.b4 .control.buf.b5 .control.buf.b6 .control.buf.b7 .control.buf.b8 -side top -padx 3 
+
+# Offset
+
+frame .control.offset
+
+frame .control.offset.in
+label .control.offset.in.text -text "Offset In" -justify left
+label .control.offset.in.off0 -text "dev\#0: -" -anchor nw -width 10 -font times
+label .control.offset.in.off1 -text "dev\#1: -" -anchor nw -width 10 -font times
+label .control.offset.in.off2 -text "dev\#2: -" -anchor nw -width 10 -font times
+label .control.offset.in.off3 -text "dev\#3: -" -anchor nw -width 10 -font times
+
+pack .control.offset.in.text .control.offset.in.off0 .control.offset.in.off1 .control.offset.in.off2 .control.offset.in.off3
+
+label .control.offset.space
+
+frame .control.offset.out
+label .control.offset.out.text -text "Offset Out" -justify left
+label .control.offset.out.off0 -text "dev\#0: -" -anchor nw -width 10 -font times
+label .control.offset.out.off1 -text "dev\#1: -" -anchor nw -width 10 -font times
+label .control.offset.out.off2 -text "dev\#2: -" -anchor nw -width 10 -font times
+label .control.offset.out.off3 -text "dev\#3: -" -anchor nw -width 10 -font times
+
+pack .control.offset.out.off3 .control.offset.out.off2 .control.offset.out.off1 .control.offset.out.off0 .control.offset.out.text -side bottom
+
+pack .control.offset.in .control.offset.space .control.offset.out -side top -fill y -padx 3 -expand 1
+
+
+pack .control.spdif .control.sync .control.space .control.buf .control.offset -side left -fill both -anchor n -expand 1
+
+
+label .statustext -text Status -justify center -relief ridge
+label .controltext -text Control -justify center -relief ridge
+
+label .statusspace
+label .controlspace
+
+pack .statustext .status .statusspace .controltext .control .controlspace -side top -anchor nw -fill both -expand 1
+
+
+proc get_bit {output sstr} {
+    set idx1 [string last [concat $sstr 1] $output]
+    set idx1 [expr $idx1 != -1]
+    return $idx1
+}
+
+proc get_val {output sstr} {
+    set val [string wordend $output [string last $sstr $output]] 
+    set val [string range $output $val [expr $val+1]]
+    return $val
+}
+
+proc get_val2 {output sstr} {
+    set val [string wordend $output [string first $sstr $output]] 
+    set val [string range $output $val [expr $val+2]]
+    return $val
+}
+
+proc get_control {} {
+    global spprof
+    global spemph
+    global spnoaud
+    global spoptical
+    global spdifin
+    global ssrate
+    global master
+    global wordclock
+    global syncsource
+    global CTRLPROG
+
+    set f [open "| $CTRLPROG control" r+]
+    set ooo [read $f 1000]
+    close $f
+#    puts $ooo
+
+    set spprof [ get_bit $ooo "pro"]
+    set spemph [ get_bit $ooo "emphasis"]
+    set spnoaud [ get_bit $ooo "dolby"]
+    set spoptical [ get_bit $ooo "opt_out"]
+    set spdifin [ expr [ get_val $ooo "spdif_in"] + 1]
+    set ssrate [ expr [ get_val $ooo "latency"] + 1]
+    set master [ expr [ get_val $ooo "master"]]
+    set wordclock [ expr [ get_val $ooo "wordclock"]]
+    set syncsource [ expr [ get_val $ooo "sync_ref"] + 1]
+}
+
+proc get_status {} {
+    global srate
+    global ctrlcom
+    
+    global adatlock1
+    global adatlock2
+    global adatlock3
+
+    global adatsync1
+    global adatsync2
+    global adatsync3
+
+    global tcbusy
+    global tcout
+    global tcvalid
+
+    global spdiferr
+    global crystal
+    global .status.spdif.text
+    global CTRLPROG
+
+
+    set f [open "| $CTRLPROG status" r+]
+    set ooo [read $f 1000]
+    close $f
+#    puts $ooo
+ 
+# samplerate
+
+    set idx1 [string last "sr48 1" $ooo]
+    set idx2 [string last "doublespeed 1" $ooo]
+    if {$idx1 >= 0} {
+	set fact1 48000
+    } else {
+	set fact1 44100
+    }
+    
+    if {$idx2 >= 0} {
+	set fact2 2 
+    } else {
+	set fact2 1 
+    }
+    set srate [expr $fact1 * $fact2]
+#   ADAT lock 
+
+    set val [get_val $ooo lockmask]
+    set adatlock1 0
+    set adatlock2 0
+    set adatlock3 0
+    if {[expr $val & 1]} {
+       set adatlock3 1
+    } 
+    if {[expr $val & 2]} {
+       set adatlock2 1
+    } 
+    if {[expr $val & 4]} {
+       set adatlock1 1
+    } 
+
+#  ADAT sync
+    set val [get_val $ooo syncmask]
+    set adatsync1 0
+    set adatsync2 0
+    set adatsync3 0
+
+    if {[expr $val & 1]} {
+       set adatsync3 1
+    } 
+    if {[expr $val & 2]} {
+       set adatsync2 1
+    } 
+    if {[expr $val & 4]} {
+       set adatsync1 1
+    } 
+
+# TC busy
+
+    set tcbusy [get_bit $ooo "busy"]
+    set tcout [get_bit $ooo "out"]
+    set tcvalid [get_bit $ooo "valid"]
+    set spdiferr [expr [get_bit $ooo "spdif_error"] == 0]
+
+#  000=64kHz, 100=88.2kHz, 011=96kHz  
+#  111=32kHz, 110=44.1kHz, 101=48kHz
+
+    set val [get_val $ooo crystalrate] 
+
+    set crystal "--.- kHz"
+    if {$val == 0} {
+        set crystal "64 kHz"
+    }
+    if {$val == 4} {
+        set crystal "88.2 kHz"
+    }
+    if {$val == 3} {
+        set crystal "96 kHz"
+    }
+    if {$val == 7} {
+        set crystal "32 kHz"
+    }
+    if {$val == 6} {
+        set crystal "44.1 kHz"
+    }
+    if {$val == 5} {
+        set crystal "48 kHz"
+    }
+    .status.spdif.sr configure -text $crystal
+}
+
+proc get_offset {} {
+    global inoffset
+    global outoffset
+    global CTRLPROG
+
+    set f [open "| $CTRLPROG mix" r+]
+    set ooo [read $f 1000]
+    close $f
+#    puts $ooo
+
+    if { [string match "*devnr*" $ooo] } {
+	set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end]
+	set val [get_val2 $ooo i_offset] 
+	.control.offset.in.off0 configure -text "dev\#0: $val"
+	set val [get_val2 $ooo o_offset] 
+	.control.offset.out.off0 configure -text "dev\#0: $val"
+    } else {
+	.control.offset.in.off0 configure -text "dev\#0: -"
+	.control.offset.out.off0 configure -text "dev\#0: -"
+    }
+    if { [string match "*devnr*" $ooo] } {
+	set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end]
+	set val [get_val2 $ooo i_offset] 
+	.control.offset.in.off1 configure -text "dev\#1: $val"
+	set val [get_val2 $ooo o_offset] 
+	.control.offset.out.off1 configure -text "dev\#1: $val"
+    } else {
+	.control.offset.in.off1 configure -text "dev\#1: -"
+	.control.offset.out.off1 configure -text "dev\#1: -"
+    }
+    if { [string match "*devnr*" $ooo] } {
+	set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end]
+	set val [get_val2 $ooo i_offset] 
+	.control.offset.in.off2 configure -text "dev\#2: $val"
+	set val [get_val2 $ooo o_offset] 
+	.control.offset.out.off2 configure -text "dev\#2: $val"
+    } else {
+	.control.offset.in.off2 configure -text "dev\#2: -"
+	.control.offset.out.off2 configure -text "dev\#2: -"
+    }
+    if { [string match "*devnr*" $ooo] } {
+	set ooo [string range $ooo [string wordend $ooo [string first devnr $ooo]] end]
+	set val [get_val2 $ooo i_offset] 
+	.control.offset.in.off3 configure -text "dev\#3: $val"
+	set val [get_val2 $ooo o_offset] 
+	.control.offset.out.off3 configure -text "dev\#3: $val"
+    } else {
+	.control.offset.in.off3 configure -text "dev\#3: -"
+	.control.offset.out.off3 configure -text "dev\#3: -"
+    }
+}
+
+
+proc get_all {} {
+get_status
+get_control
+get_offset
+}
+
+# main
+while {1} {
+  after 200 
+  get_all
+  update
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/sysctl/vm.txt linux/Documentation/sysctl/vm.txt
--- linux.orig/Documentation/sysctl/vm.txt	Mon Sep 10 21:36:25 2001
+++ linux/Documentation/sysctl/vm.txt	Tue May 28 22:39:30 2002
@@ -21,6 +21,7 @@
 - buffermem
 - freepages
 - kswapd
+- max_map_count
 - overcommit_memory
 - page-cluster
 - pagecache
@@ -167,6 +168,19 @@
 and don't use much of it.
 
 Look at: mm/mmap.c::vm_enough_memory() for more information.
+
+==============================================================
+
+max_map_count:
+
+This file contains the maximum number of memory map areas a
+process may have. Memory map areas are used as a side-effect
+of calling malloc, directly by mmap and mprotect, and also
+when loading shared libraries.
+
+While most applications need less than a thousand maps,
+certain programs, particularly malloc debuggers, may consume 
+lots of them, e.g. up to one or two maps per allocation.
 
 ==============================================================
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/sysrq.txt linux/Documentation/sysrq.txt
--- linux.orig/Documentation/sysrq.txt	Tue Sep 18 05:52:35 2001
+++ linux/Documentation/sysrq.txt	Tue May 28 22:39:27 2002
@@ -153,7 +153,7 @@
 and 4 functions are exported for interface to it: __sysrq_lock_table,
 __sysrq_unlock_table, __sysrq_get_key_op, and __sysrq_put_key_op. The
 functions __sysrq_swap_key_ops and __sysrq_swap_key_ops_nolock are defined
-in the header itself, and the REGISTER and UNREGISTER macros are built fromi
+in the header itself, and the REGISTER and UNREGISTER macros are built from
 these. More complex (and dangerous!) manipulations of the table are possible
 using these functions, but you must be careful to always lock the table before
 you read or write from it, and to unlock it again when you are done. (And of
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/usb/auerswald.txt linux/Documentation/usb/auerswald.txt
--- linux.orig/Documentation/usb/auerswald.txt	Thu Jan  1 00:00:00 1970
+++ linux/Documentation/usb/auerswald.txt	Tue May 28 22:39:28 2002
@@ -0,0 +1,30 @@
+		Auerswald USB kernel driver
+		===========================
+
+What is it? What can I do with it?
+==================================
+The auerswald USB kernel driver connects your linux 2.4.x
+system to the auerswald usb-enabled devices.
+
+There are two types of auerswald usb devices:
+a) small PBX systems (ISDN)
+b) COMfort system telephones (ISDN)
+
+The driver installation creates the devices
+/dev/usb/auer0..15. These devices carry a vendor-
+specific protocol. You may run all auerswald java
+software on it. The java software needs a native
+library "libAuerUsbJNINative.so" installed on
+your system. This library is available from
+auerswald and shipped as part of the java software.
+
+You may create the devices with:
+	mknod -m 666 /dev/usb/auer0 c 180 112
+	...
+	mknod -m 666 /dev/usb/auer15 c 180 127
+
+Future plans
+============
+- Connection to ISDN4LINUX (the hisax interface)
+
+The maintainer of this driver is wmues@nexgo.de
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/usb/brlvger.txt linux/Documentation/usb/brlvger.txt
--- linux.orig/Documentation/usb/brlvger.txt	Thu Jan  1 00:00:00 1970
+++ linux/Documentation/usb/brlvger.txt	Tue May 28 22:39:24 2002
@@ -0,0 +1,36 @@
+Kernel Driver for the Tieman Voyager Braille Display (USB)
+
+Authors:
+Stéphane Dalton <sdalton@videotron.ca>
+Stéphane Doyon  <s.doyon@videotron.ca>
+
+Version 0.8, April 2002
+
+The brlvger driver supports a Braille display (aka Braille terminal)
+model Voyager from Tieman.
+
+The driver has been in heavy use for about six months now (as of April
+2002) by a very few users (about 3-4), who say it has worked very well
+for them.
+
+We have tested it with a Voyager 44, but it should also support
+the Voyager 70.
+
+This driver implements a character device which allows userspace programs
+access to the braille displays raw functions. You still need a userspace
+program to perform the screen-review functions and control the
+display. Get BRLTTY from http://mielke.cc/brltty/ (version 2.99.8 or
+later). It has a Voyager driver which interfaces with this kernel driver.
+
+The interface is through a character device, major 180, minor 128, called
+"brlvger" under devfs.
+
+Many thanks to the Tieman people: Corand van Strien, Ivar Illing, Daphne
+Vogelaar and Ingrid Vogel. They provided us with a Braille display (as
+well as programming information) so that we could write this driver. They
+replaced the display when it broke and they answered our technical
+questions. It is very motivating when companies take an interest in such
+projects and are so supportive.
+
+Thanks to Andor Demarteau <ademarte@students.cs.uu.nl> who got this whole
+project started and beta-tested all our early buggy attempts.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/usb/ehci.txt linux/Documentation/usb/ehci.txt
--- linux.orig/Documentation/usb/ehci.txt	Thu Jan  1 00:00:00 1970
+++ linux/Documentation/usb/ehci.txt	Tue May 28 22:39:28 2002
@@ -0,0 +1,171 @@
+26-Apr-2002
+
+The EHCI driver is used to talk to high speed USB 2.0 devices using
+USB 2.0-capable host controller hardware.  The USB 2.0 standard is
+compatible with the USB 1.1 standard. It defines three transfer speeds:
+
+    - "High Speed" 480 Mbit/sec (60 MByte/sec)
+    - "Full Speed" 12 Mbit/sec (1.5 MByte/sec)
+    - "Low Speed" 1.5 Mbit/sec
+
+USB 1.1 only addressed full speed and low speed.  High speed devices
+can be used on USB 1.1 systems, but they slow down to USB 1.1 speeds. 
+
+USB 1.1 devices may also be used on USB 2.0 systems.  When plugged
+into an EHCI controller, they are given to a USB 1.1 "companion"
+controller, which is a OHCI or UHCI controller as normally used with
+such devices.  When USB 1.1 devices plug into USB 2.0 hubs, they
+interact with the EHCI controller through a "Transaction Translator"
+(TT) in the hub, which turns low or full speed transactions into
+high speed "split transactions" that don't waste transfer bandwidth.
+
+At this writing, this driver has been seen to work with implementations
+of EHCI from (in alphabetical order):  Intel, NEC, Philips, and VIA.
+
+At this writing, high speed devices are finally beginning to appear.
+While usb-storage devices have been available for some time (working
+quite speedily on the 2.4 version of this driver), hubs have only
+very recently become available.
+
+Note that USB 2.0 support involves more than just EHCI.  It requires
+other changes to the Linux-USB core APIs, including the hub driver,
+but those changes haven't needed to really change the basic "usbcore"
+APIs exposed to USB device drivers.
+
+- David Brownell
+  <dbrownell@users.sourceforge.net>
+
+
+FUNCTIONALITY
+
+This driver is regularly tested on x86 hardware, and has also been
+used on PPC hardware so big/little endianness issues should be gone.
+It's believed to do all the right PCI magic so that I/O works even on
+systems with interesting DMA mapping issues.
+
+At this writing the driver should comfortably handle all control and bulk
+transfers, including requests to USB 1.1 devices through transaction
+translators (TTs) in USB 2.0 hubs.  However, there some situations where
+the hub driver needs to clear TT error state, which it doesn't yet do.
+
+Interrupt transfer support is newly functional and not yet as robust as
+control and bulk traffic.  As yet there is no support for split transaction
+scheduling for interrupt transfers, which means among other things that
+connecting USB 1.1 hubs, keyboards, and mice to USB 2.0 hubs won't work.
+Connect them to USB 1.1 hubs, or to a root hub.
+
+Isochronous (ISO) transfer support is also newly functional.  No production
+high speed devices are available which would need it (though high quality
+webcams are in the works!).  Note that split transaction support for ISO
+transfers can't share much code with the code for high speed ISO transfers,
+since EHCI represents these with a different data structure.  So for now,
+most USB audio and video devices have the same restrictions as hubs, mice,
+and keyboards:  don't connect them using high speed USB hubs.
+
+The EHCI root hub code should hand off USB 1.1 devices to its companion
+controller.  This driver doesn't need to know anything about those
+drivers; a OHCI or UHCI driver that works already doesn't need to change
+just because the EHCI driver is also present.
+
+There are some issues with power management; suspend/resume doesn't
+behave quite right at the moment.
+
+
+USE BY
+
+Assuming you have an EHCI controller (on a PCI card or motherboard)
+and have compiled this driver as a module, load this like:
+
+    # modprobe ehci-hcd
+
+and remove it by:
+
+    # rmmod ehci-hcd
+
+You should also have a driver for a "companion controller", such as
+"ohci-hcd", "usb-ohci", "usb-uhci", or "uhci".  In case of any trouble
+with the EHCI driver, remove its module and then the driver for that
+companion controller will take over (at lower speed) all the devices
+that were previously handled by the EHCI driver.
+
+Module parameters (pass to "modprobe") include:
+
+    log2_irq_thresh (default 0):
+	Log2 of default interrupt delay, in microframes.  The default
+	value is 0, indicating 1 microframe (125 usec).  Maximum value
+	is 6, indicating 2^6 = 64 microframes.  This controls how often
+	the EHCI controller can issue interrupts.
+
+The EHCI interrupt handler just acknowledges interrupts and schedules
+a tasklet to handle whatever needs handling.  That keeps latencies low,
+no matter how often interrupts are issued.
+
+Device drivers shouldn't care whether they're running over EHCI or not,
+but they may want to check for "usb_device->speed == USB_SPEED_HIGH".
+High speed devices can do things that full speed (or low speed) ones
+can't, such as "high bandwidth" periodic (interrupt or ISO) transfers.
+Also, some values in device descriptors (such as polling intervals for
+periodic transfers) use different encodings when operating at high speed.
+
+
+PERFORMANCE
+
+USB 2.0 throughput is gated by two main factors:  how fast the host
+controller can process requests, and how fast devices can respond to
+them.  The 480 Mbit/sec "raw transfer rate" is obeyed by all devices,
+but aggregate throughput is also affected by issues like delays between
+individual high speed packets, driver intelligence, and of course the
+overall system load.  Latency is also a performance concern.
+
+Bulk transfers are most often used where throughput is an issue.  It's
+good to keep in mind that bulk transfers are always in 512 byte packets,
+and at most 13 of those fit into one USB 2.0 microframe.  Eight USB 2.0
+microframes fit in a USB 1.1 frame; a microframe is 1 msec/8 = 125 usec.
+
+Hardware Performance
+
+At this writing, individual USB 2.0 devices tend to max out at around
+20 MByte/sec transfer rates.  This is of course subject to change;
+and some devices now go faster, while others go slower.
+
+The NEC implementation of EHCI seems to have a hardware bottleneck
+at around 28 MByte/sec aggregate transfer rate.  While this is clearly
+enough for a single device at 20 MByte/sec, putting three such devices
+onto one bus does not get you 60 MByte/sec.  The issue appears to be
+that the controller hardware won't do concurrent USB and PCI access,
+so that it's only trying six (or maybe seven) USB transactions each
+microframe rather than thirteen.  (Seems like a reasonable trade off
+for a product that beat all the others to market by over a year!)
+It's expected that newer implementations will better this, throwing
+more silicon real estate at the problem so that new motherboard chip
+sets will get closer to that 60 MByte/sec target.
+
+There's a minimum latency of one microframe (125 usec) for the host
+to receive interrupts from the EHCI controller indicating completion
+of requests.  That latency is tunable; there's a module option.  By
+default ehci-hcd driver uses the minimum latency, which means that if
+you issue a control or bulk request you can often expect to learn that
+it completed in less than 250 usec (depending on transfer size).
+
+Software Performance
+
+To get even 20 MByte/sec transfer rates, Linux-USB device drivers will
+need to keep the EHCI queue full.  That means issuing large requests,
+or using bulk queuing if a series of small requests needs to be issued.
+When drivers don't do that, their performance results will show it.
+
+In typical situations, a usb_bulk_msg() loop writing out 4 KB chunks is
+going to waste more than half the USB 2.0 bandwidth.  Delays between the
+I/O completion and the driver issuing the next request will take longer
+than the I/O.  If that same loop used 16 KB chunks, it'd be better; a
+sequence of 128 KB chunks would waste a lot less.
+
+But rather than depending on such large I/O buffers to make synchronous
+I/O be efficient, it's better to just queue all several (bulk) requests
+to the HC, and wait for them all to complete (or be canceled on error).
+Such URB queuing should work with all the USB 1.1 HC drivers too.
+
+TBD:  Interrupt and ISO transfer performance issues.  Those periodic
+transfers are fully scheduled, so the main issue is likely to be how
+to trigger "high bandwidth" modes.
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/usb/ibmcam.txt linux/Documentation/usb/ibmcam.txt
--- linux.orig/Documentation/usb/ibmcam.txt	Sun Apr  2 22:19:56 2000
+++ linux/Documentation/usb/ibmcam.txt	Tue May 28 22:39:31 2002
@@ -25,12 +25,19 @@
 
 SUPPORTED CAMERAS:
 
-IBM "C-It" camera, also known as "Xirlink PC Camera"
+Xirlink "C-It" camera, also known as "IBM PC Camera".
 The device uses proprietary ASIC (and compression method);
 it is manufactured by Xirlink. See http://www.xirlink.com/
 http://www.ibmpccamera.com or http://www.c-itnow.com/ for
 details and pictures.
 
+This very chipset ("X Chip", as marked at the factory)
+is used in several other cameras, and they are supported
+as well:
+
+- IBM NetCamera
+- Veo Stingray
+
 The Linux driver was developed with camera with following
 model number (or FCC ID): KSX-XVP510. This camera has three
 interfaces, each with one endpoint (control, iso, iso). This
@@ -50,12 +57,30 @@
 Such type of cameras is referred to as "model 2". They are supported
 (with exception of 352x288 native mode).
 
+Some IBM NetCameras (Model 4) are made to generate only compressed
+video streams. This is great for performance, but unfortunately
+nobody knows how to decompress the stream :-( Therefore, these
+cameras are *unsupported* and if you try to use one of those, all
+you get is random colored horizontal streaks, not the image!
+If you have one of those cameras, you probably should return it
+to the store and get something that is supported.
+
+Tell me more about all that "model" business
+--------------------------------------------
+
+I just invented model numbers to uniquely identify flavors of the
+hardware/firmware that were sold. It was very confusing to use
+brand names or some other internal numbering schemes. So I found
+by experimentation that all Xirlink chipsets fall into four big
+classes, and I called them "models". Each model is programmed in
+its own way, and each model sends back the video in its own way.
+
 Quirks of Model 2 cameras:
 -------------------------
 
 Model 2 does not have hardware contrast control. Corresponding V4L
-control is not used at the moment. It may be possible to implement
-contrast control in software, at cost of extra processor cycles.
+control is implemented in software, which is not very nice to your
+CPU, but at least it works.
 
 This driver provides 352x288 mode by switching the camera into
 quasi-352x288 RGB mode (800 Kbits per frame) essentially limiting
@@ -67,17 +92,24 @@
 the frame rate at slowest setting, but I had to move it pretty much down
 the scale (so that framerate option barely matters). I also noticed that
 camera after first powering up produces frames slightly faster than during
-consecutive uses. All this means that if you use videosize=2 (which is
+consecutive uses. All this means that if you use 352x288 (which is
 default), be warned - you may encounter broken picture on first connect;
 try to adjust brightness - brighter image is slower, so USB will be able
 to send all data. However if you regularly use Model 2 cameras you may
-prefer videosize=1 which makes perfectly good I420, with no scaling and
+prefer 176x144 which makes perfectly good I420, with no scaling and
 lesser demands on USB (300 Kbits per second, or 26 frames per second).
 
+Another strange effect of 352x288 mode is the fine vertical grid visible
+on some colored surfaces. I am sure it is caused by me not understanding
+what the camera is trying to say. Blame trade secrets for that.
+
 The camera that I had also has a hardware quirk: if disconnected,
 it needs few minutes to "relax" before it can be plugged in again
 (poorly designed USB processor reset circuit?)
 
+[Veo Stingray with Product ID 0x800C is also Model 2, but I haven't
+observed this particular flaw in it.]
+
 Model 2 camera can be programmed for very high sensitivity (even starlight
 may be enough), this makes it convenient for tinkering with. The driver
 code has enough comments to help a programmer to tweak the camera
@@ -98,12 +130,14 @@
 precompile all modules, so you can go directly to the next
 section "HOW TO USE THE DRIVER".
 
-The driver consists of two files in usb/ directory:
-ibmcam.c and ibmcam.h These files are included into the
-Linux kernel build process if you configure the kernel
-for CONFIG_USB_IBMCAM. Run "make xconfig" and in USB section
-you will find the IBM camera driver. Select it, save the
-configuration and recompile.
+The ibmcam driver uses usbvideo helper library (module),
+so if you are studying the ibmcam code you will be led there.
+
+The driver itself consists of only one file in usb/ directory:
+ibmcam.c. This file is included into the Linux kernel build
+process if you configure the kernel for CONFIG_USB_IBMCAM.
+Run "make xconfig" and in USB section you will find the IBM
+camera driver. Select it, save the configuration and recompile.
 
 HOW TO USE THE DRIVER:
 
@@ -112,6 +146,13 @@
 settings than V4L can operate, so some settings are done using
 module options.
 
+To begin with, on most modern Linux distributions the driver
+will be automatically loaded whenever you plug the supported
+camera in. Therefore, you don't need to do anything. However
+if you want to experiment with some module parameters then
+you can load and unload the driver manually, with camera
+plugged in or unplugged.
+
 Typically module is installed with command 'modprobe', like this:
 
 # modprobe ibmcam framerate=1
@@ -138,7 +179,7 @@
 init_hue        Integer         0-255 [128]     init_hue=115
 lighting        Integer         0-2* [1]        lighting=2
 sharpness       Integer         0-6* [4]        sharpness=3
-videosize       Integer         0-2* [2]        videosize=1
+size            Integer         0-2* [2]        size=1
 
 Options for Model 2 only:
 
@@ -181,6 +222,11 @@
                                            this is a little faster but may
                                            produce flicker if frame rate is
                                            too high and Isoc data gets lost.
+                FLAGS_NO_DECODING      128 This flag turns the video stream
+                                           decoder off, and dumps the raw
+                                           Isoc data from the camera into
+                                           the reading process. Useful to
+                                           developers, but not to users.
 
 framerate       This setting controls frame rate of the camera. This is
                 an approximate setting (in terms of "worst" ... "best")
@@ -227,35 +273,38 @@
                 be greeted with "snowy" image. Default is 4. Model 2
                 cameras do not support this feature.
 
-videosize       This setting chooses one if three image sizes that are
-                supported by this driver. Camera supports more, but
+size            This setting chooses one of several image sizes that are
+                supported by this driver. Cameras may support more, but
                 it's difficult to reverse-engineer all formats.
                 Following video sizes are supported:
 
-                videosize=0     128x96  (Model 1 only)
-                videosize=1     176x144
-                videosize=2     352x288
-                videosize=3     320x240 (Model 2 only)
-                videosize=4     352x240 (Model 2 only)
+                size=0     128x96  (Model 1 only)
+                size=1     160x120
+                size=2     176x144
+                size=3     320x240 (Model 2 only)
+                size=4     352x240 (Model 2 only)
+                size=5     352x288
+                size=6     640x480 (Model 3 only)
 
-                The last one (352x288) is the native size of the sensor
-                array, so it's the best resolution camera (Model 1) can
+                The 352x288 is the native size of the Model 1 sensor
+                array, so it's the best resolution the camera can
                 yield. The best resolution of Model 2 is 176x144, and
                 larger images are produced by stretching the bitmap.
+                Model 3 has sensor with 640x480 grid, and it works too,
+                but the frame rate will be exceptionally low (1-2 FPS);
+                it may be still OK for some applications, like security.
                 Choose the image size you need. The smaller image can
                 support faster frame rate. Default is 352x288.
 
+For more information and the Troubleshooting FAQ visit this URL:
+
+                http://www.linux-usb.org/ibmcam/
+
 WHAT NEEDS TO BE DONE:
 
-- The box freezes if camera is unplugged after being used (OHCI).
-  Workaround: remove usb-ohci module first.
-- On occasion camera (model 1) does not start properly (xawtv reports
-  errors), or camera produces negative image (funny colors.)
-  Workaround: reload the driver module. Reason: [1].
 - The button on the camera is not used. I don't know how to get to it.
   I know now how to read button on Model 2, but what to do with it?
 
-[1]
 - Camera reports its status back to the driver; however I don't know
   what returned data means. If camera fails at some initialization
   stage then something should be done, and I don't do that because
@@ -263,26 +312,13 @@
   concern because Model 2 uses different commands which do not return
   status (and seem to complete successfully every time).
 
-VIDEO SIZE AND IMAGE SIZE
-
-Camera produces picture X by Y pixels. This is camera-specific and can be
-altered by programming the camera accordingly. This image is placed onto
-larger (or equal) area W by H, this is V4L image. At this time the driver
-uses V4L image size (W by H) 352x288 pixels because many programs (such
-as xawtv) expect quite specific sizes and don't want to deal with arbitrary,
-camera-specific sizes. However this approach "hides" real image size, and
-application always sees the camera as producing only 352x288 image. It is
-possible to change the V4L image size to 128x96, and then if camera is
-switched to 128x96 mode then xawtv will correctly accept this image size. But
-many other popular sizes (such as 176x144) will not be welcomed. This is the
-reason why all camera images are at this time placed onto 352x288 "canvas",
-and size of that canvas (V4L) is reported to applications. It will be easy
-to add options to control the canvas size, but it will be application-
-specific because not all applications are ready to work with variety of
-camera-specific sizes.
+- Some flavors of Model 4 NetCameras produce only compressed video
+  streams, and I don't know how to decode them.
 
 CREDITS:
 
 The code is based in no small part on the CPiA driver by Johannes Erdfelt,
 Randy Dunlap, and others. Big thanks to them for their pioneering work on that
 and the USB stack.
+
+I also thank John Lightsey for his donation of the Veo Stingray camera.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/usb/proc_usb_info.txt linux/Documentation/usb/proc_usb_info.txt
--- linux.orig/Documentation/usb/proc_usb_info.txt	Tue Aug 22 16:06:31 2000
+++ linux/Documentation/usb/proc_usb_info.txt	Tue May 28 22:39:15 2002
@@ -1,32 +1,99 @@
 /proc/bus/usb filesystem output
 ===============================
-(version 2000.08.15)
+(version 2002.03.18)
 
 
-The /proc filesystem for USB devices generates
-/proc/bus/usb/drivers and /proc/bus/usb/devices.
+The /proc filesystem for USB devices provides /proc/bus/usb/drivers
+and /proc/bus/usb/devices, as well as /proc/bus/usb/BBB/DDD files.
 
-/proc/bus/usb/drivers lists the registered drivers,
-one per line, with each driver's USB minor dev node
-number range if applicable.
 
-**NOTE**: If /proc/bus/usb appears empty, you need
-          to mount the filesystem, issue the command (as root):
+**NOTE**: If /proc/bus/usb appears empty, and a host controller
+	  driver has been linked, then you need to mount the
+	  filesystem.  Issue the command (as root):
 
-      mount -t usbdevfs none /proc/bus/usb
+      mount -t usbfs none /proc/bus/usb
 
 	  An alternative and more permanent method would be to add
 
-      none  /proc/bus/usb  usbdevfs  defaults  0  0
+      none  /proc/bus/usb  usbfs  defaults  0  0
 
-	  to /etc/fstab.  This will mount usbdevfs at each reboot.
+	  to /etc/fstab.  This will mount usbfs at each reboot.
 	  You can then issue `cat /proc/bus/usb/devices` to extract
-	  USB device information.
+	  USB device information, and user mode drivers can use usbfs 
+	  to interact with USB devices.
 
-For more information on mounting the usbdevfs file system, see the
+	  There are a number of mount options supported by usbfs.
+	  Consult the source code (linux/drivers/usb/inode.c) for
+	  information about those options.
+
+**NOTE**: The filesystem has been renamed from "usbdevfs" to
+	  "usbfs", to reduce confusion with "devfs".  You may
+	  still see references to the older "usbdevfs" name.
+
+For more information on mounting the usbfs file system, see the
 "USB Device Filesystem" section of the USB Guide. The latest copy 
 of the USB Guide can be found at http://www.linux-usb.org/
 
+
+THE /proc/bus/usb/BBB/DDD FILES:
+--------------------------------
+Each connected USB device has one file.  The BBB indicates the bus
+number.  The DDD indicates the device address on that bus.  Both
+of these numbers are assigned sequentially, and can be reused, so
+you can't rely on them for stable access to devices.  For example,
+it's relatively common for devices to re-enumerate while they are
+still connected (perhaps someone jostled their power supply, hub,
+or USB cable), so a device might be 002/027 when you first connect
+it and 002/048 sometime later.
+
+These files can be read as binary data.  The binary data consists
+of first the device descriptor, then the descriptors for each
+configuration of the device.  That information is also shown in
+text form by the /proc/bus/usb/devices file, described later.
+
+These files may also be used to write user-level drivers for the USB
+devices.  You would open the /proc/bus/usb/BBB/DDD file read/write,
+read its descriptors to make sure it's the device you expect, and then
+bind to an interface (or perhaps several) using an ioctl call.  You
+would issue more ioctls to the device to communicate to it using
+control, bulk, or other kinds of USB transfers.  The IOCTLs are
+listed in the <linux/usbdevice_fs.h> file, and at this writing the
+source code (linux/drivers/usb/devio.c) is the primary reference
+for how to access devices through those files.
+
+Note that since by default these BBB/DDD files are writable only by
+root, only root can write such user mode drivers.  You can selectively
+grant read/write permissions to other users by using "chmod".  Also,
+usbfs mount options such as "devmode=0666" may be helpful.
+
+
+
+THE /proc/bus/usb/drivers FILE:
+-------------------------------
+Each of the USB device drivers linked into your kernel (statically,
+or dynamically using "modprobe") is listed in the "drivers" file.
+Here's an example from one system:
+
+         usbdevfs
+         hub
+  0- 15: usblp
+         usbnet
+         serial
+         usb-storage
+         pegasus
+
+If you see this file, "usbdevfs" and "hub" will always be listed,
+since those are part of the "usbcore" framework.
+
+Drivers that use the USB major number (180) to provide character devices
+will include a range of minor numbers, as shown above for the "usblp"
+(actually "printer.o") module.  USB device drivers can of course use any
+major number, but it's easy to use the USB range since there's explicit
+support for subdividing it in the USB device driver framework.
+
+
+THE /proc/bus/usb/devices FILE:
+-------------------------------
 In /proc/bus/usb/devices, each device's output has multiple
 lines of ASCII output.
 I made it ASCII instead of binary on purpose, so that someone
@@ -34,8 +101,6 @@
 auxiliary program.  However, with an auxiliary program, the numbers
 in the first 4 columns of each "T:" line (topology info:
 Lev, Prnt, Port, Cnt) can be used to build a USB topology diagram.
-(I think.  I haven't proved this, but I have tested it with 3
-different topo/connections and it looked possible.)
 
 Each line is tagged with a one-character ID for that line:
 
@@ -73,14 +138,30 @@
 |   |__Bus number
 |__Topology info tag
 
+    Speed may be:
+    	1.5	Mbit/s for low speed USB
+	12	Mbit/s for full speed USB
+	480	Mbit/s for high speed USB (added for USB 2.0)
+
 
 Bandwidth info:
 B:  Alloc=ddd/ddd us (xx%), #Int=ddd, #Iso=ddd
-|   |                       |         |__Number if isochronous requests
+|   |                       |         |__Number of isochronous requests
 |   |                       |__Number of interrupt requests
 |   |__Total Bandwidth allocated to this bus
 |__Bandwidth info tag
 
+    Bandwidth allocation is an approximation of how much of one frame
+    (millisecond) is in use.  It reflects only periodic transfers, which
+    are the only transfers that reserve bandwidth.  Control and bulk
+    transfers use all other bandwidth, including reserved bandwidth that
+    is not used for transfers (such as for short packets).
+    
+    The percentage is how much of the "reserved" bandwidth is scheduled by
+    those transfers.  For a low or full speed bus (loosely, "USB 1.1"),
+    90% of the bus bandwidth is reserved.  For a high speed bus (loosely,
+    "USB 2.0") 80% is reserved.
+
 
 Device descriptor info & Product ID info:
 
@@ -109,37 +190,55 @@
 
 S:  Manufacturer=ssss
 |   |__Manufacturer of this device as read from the device.
+|      For USB host controller drivers (virtual root hubs) this may
+|      be omitted, or (for newer drivers) will identify the kernel
+|      version and the driver which provides this hub emulation.
 |__String info tag
 
 S:  Product=ssss
-|   |__Product description of this device as read from the device,
-|      except that it is a generated string for USB host controllers
-|      (virtual root hubs), in the form "USB *HCI Root Hub".
+|   |__Product description of this device as read from the device.
+|      For older USB host controller drivers (virtual root hubs) this
+|      indicates the driver; for newer ones, it's a product (and vendor)
+|      description that often comes from the kernel's PCI ID database.
 |__String info tag
 
 S:  SerialNumber=ssss
-|   |__Serial Number of this device as read from the device,
-|      except that it is a generated string for USB host controllers
-|      (virtual root hubs), and represents the host controller's
-|      unique identification in the system (currently I/O or
-|      memory-mapped base address).
+|   |__Serial Number of this device as read from the device.
+|      For USB host controller drivers (virtual root hubs) this is
+|      some unique ID, normally a bus ID (address or slot name) that
+|      can't be shared with any other device.
 |__String info tag
 
 
+
 Configuration descriptor info:
 
-C:  #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA
-|   |       |       |      |__MaxPower in mA
-|   |       |       |__Attributes
-|   |       |__ConfiguratioNumber
-|   |__NumberOfInterfaces
+C:* #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA
+| | |       |       |      |__MaxPower in mA
+| | |       |       |__Attributes
+| | |       |__ConfiguratioNumber
+| | |__NumberOfInterfaces
+| |__ "*" indicates the active configuration (others are " ")
 |__Config info tag
+    
+    USB devices may have multiple configurations, each of which act
+    rather differently.  For example, a bus-powered configuration
+    might be much less capable than one that is self-powered.  Only
+    one device configuration can be active at a time; most devices
+    have only one configuration.
+
+    Each configuration consists of one or more interfaces.  Each
+    interface serves a distinct "function", which is typically bound
+    to a different USB device driver.  One common example is a USB
+    speaker with an audio interface for playback, and a HID interface
+    for use with software volume control.
 
 
 Interface descriptor info (can be multiple per Config):
 
 I:  If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=ssss
 |   |      |      |       |             |      |       |__Driver name
+|   |      |      |       |             |      |          or "(none)"
 |   |      |      |       |             |      |__InterfaceProtocol
 |   |      |      |       |             |__InterfaceSubClass
 |   |      |      |       |__InterfaceClass
@@ -148,16 +247,38 @@
 |   |__InterfaceNumber
 |__Interface info tag
 
+    A given interface may have one or more "alternate" settings.
+    For example, default settings may not use more than a small
+    amount of periodic bandwidth.  To use significant fractions
+    of bus bandwidth, drivers must select a non-default altsetting.
+    
+    Only one setting for an interface may be active at a time, and
+    only one driver may bind to an interface at a time.  Most devices
+    have only one alternate setting per interface.
+
 
 Endpoint descriptor info (can be multiple per Interface):
 
 E:  Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=dddms
-E:  Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=dddms
-|   |        |            |         |__Interval
+|   |        |            |         |__Interval (max) between transfers
 |   |        |            |__EndpointMaxPacketSize
 |   |        |__Attributes(EndpointType)
 |   |__EndpointAddress(I=In,O=Out)
 |__Endpoint info tag
+
+    The interval is nonzero for all periodic (interrupt or isochronous)
+    endpoints.  For high speed endpoints the transfer interval may be
+    measured in microseconds rather than milliseconds.
+
+    For high speed periodic endpoints, the "MaxPacketSize" reflects
+    the per-microframe data transfer size.  For "high bandwidth"
+    endpoints, that can reflect two or three packets (for up to
+    3KBytes every 125 usec) per endpoint.
+
+    With the Linux-USB stack, periodic bandwidth reservations use the
+    transfer intervals and sizes provided by URBs, which can be less
+    than those found in endpoint descriptor.
+
 
 =======================================================================
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/usb/usb-serial.txt linux/Documentation/usb/usb-serial.txt
--- linux.orig/Documentation/usb/usb-serial.txt	Mon Feb 25 19:37:52 2002
+++ linux/Documentation/usb/usb-serial.txt	Tue May 28 22:39:15 2002
@@ -95,12 +95,13 @@
   Kroah-Hartman at greg@kroah.com
 
 
-Compaq iPAQ driver
+Compaq iPAQ, HP Jornada and Casio EM500 driver
 
-  This driver can be used to connect to Compaq iPAQ PDAs running
-  Windows CE 3.0 using a USB autosync cable. It has been tested only on
-  the Compaq H3135. It should work with the H3600 and later models too.
-  It may work with other CE based handhelds as well.
+  This driver can be used to connect to Compaq iPAQ, HP Jornada and Casio EM500
+  PDAs running Windows CE 3.0 or PocketPC 2002 using a USB cable/cradle. It
+  has been tested only on the Compaq H3135, but is rumoured to work on
+  with the H3600 and later models as well as the Jornada 548 and 568.
+  With minor modifications, it may work for other CE based handhelds too.
 
   The driver presents a serial interface (usually on /dev/ttyUSB0) over
   which one may run ppp and establish a TCP/IP link to the iPAQ. Once this
@@ -109,11 +110,14 @@
   kbytes/sec for download/upload to the iPAQ.
 
   The driver works intermittently with the usb-uhci driver but quite
-  reliably with the uhci driver. Make sure you have the right driver
-  loaded - usb-uhci is often the default.
+  reliably with the uhci driver. However, performance is much better
+  with usb-uhci. It does not seem to work with ohci at all.
 
   You must setup hotplug to invoke pppd as soon as the iPAQ is connected.
-  A ppp script like the one below may be used:
+  A ppp script like the one below should be kept in the file
+  /etc/hotplug/usb/ipaq Remember to chmod +x. Make sure there are no
+  options in /etc/ppp/options or ~/.ppprc which conflict with the ones
+  given below.
 
 	#!/bin/bash
 
@@ -133,7 +137,7 @@
   On connecting the cable, you should see the usual "Device Connected",
   "User Authenticated" messages flash by on your iPAQ. Once connected,
   you can use Win CE programs like ftpView, Pocket Outlook from the iPAQ
-  and other synce utilities from the Linux side. Remember to enable IP
+  and xcerdisp, synce utilities from the Linux side. Remember to enable IP
   forwarding. 
 
   To use Pocket IE, follow the instructions given at
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/video4linux/bttv/CARDLIST linux/Documentation/video4linux/bttv/CARDLIST
--- linux.orig/Documentation/video4linux/bttv/CARDLIST	Wed Oct 17 21:19:20 2001
+++ linux/Documentation/video4linux/bttv/CARDLIST	Tue May 28 22:39:16 2002
@@ -7,13 +7,13 @@
   card=5 - Diamond DTV2000
   card=6 - AVerMedia TVPhone
   card=7 - MATRIX-Vision MV-Delta
-  card=8 - Fly Video II (Bt848)
-  card=9 - TurboTV
+  card=8 - FlyVideo II (Bt848) LR26
+  card=9 - IXMicro TurboTV
   card=10 - Hauppauge (bt878)
   card=11 - MIRO PCTV pro
   card=12 - ADS Technologies Channel Surfer TV
   card=13 - AVerMedia TVCapture 98
-  card=14 - Aimslab VHX
+  card=14 - Aimslab Video Highway Xtreme (VHX)
   card=15 - Zoltrix TV-Max
   card=16 - Pixelview PlayTV (bt878)
   card=17 - Leadtek WinView 601
@@ -21,7 +21,7 @@
   card=19 - LifeView FlyKit w/o Tuner
   card=20 - CEI Raffles Card
   card=21 - Lucky Star Image World ConferenceTV
-  card=22 - Phoebe Tv Master + FM
+  card=22 - Phoebe Tv Master + FM (CPH050)
   card=23 - Modular Technology MM205 PCTV, bt878
   card=24 - [many vendors] CPH05X/06X (bt878)
   card=25 - Terratec/Vobis TV-Boostar
@@ -54,12 +54,12 @@
   card=52 - Pinnacle PCTV Studio Pro
   card=53 - Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS
   card=54 - Lifetec LT 9415 TV (LR90 Rev.F)
-  card=55 - BESTBUY Easy TV
+  card=55 - BESTBUY Easy TV (CPH031)
   card=56 - FlyVideo '98/FM
-  card=57 - GrandTec 'Grand Video Capture'
-  card=58 - Phoebe TV Master Only (No FM)
-  card=59 - TV Capturer
-  card=60 - MM100PCTV
+  card=57 - GrandTec 'Grand Video Capture' (Bt848)
+  card=58 - Phoebe TV Master Only (No FM) CPH060
+  card=59 - TV Capturer (CPH03X)
+  card=60 - Modular Technology MM100PCTV
   card=61 - AG Electronics GMV1
   card=62 - BESTBUY Easy TV (bt878)
   card=63 - ATI TV-Wonder
@@ -72,6 +72,12 @@
   card=70 - PV-BT878P+
   card=71 - Flyvideo 98EZ (capture only)
   card=72 - Prolink PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)
+  card=73 - Sensoray 311
+  card=74 - RemoteVision MX (RV605)
+  card=75 - Powercolor MTV878/ MTV878R/ MTV878F
+  card=76 - Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)
+  card=77 - GrandTec Multi Capture Card (Bt878)
+  card=78 - AOPEN VA1000
 
 tuner.o
   type=0 - Temic PAL (4002 FH5)
@@ -94,7 +100,7 @@
   type=17 - Philips NTSC_M (MK2)
   type=18 - Temic PAL_I (4066 FY5)
   type=19 - Temic PAL* auto (4006 FN5)
-  type=20 - Temic PAL (4009 FR5)
+  type=20 - Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)
   type=21 - Temic NTSC (4039 FR5)
   type=22 - Temic PAL/SECAM multi (4046 FM5)
   type=23 - Philips PAL_DK
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/video4linux/bttv/Cards linux/Documentation/video4linux/bttv/Cards
--- linux.orig/Documentation/video4linux/bttv/Cards	Wed Oct 17 21:19:20 2001
+++ linux/Documentation/video4linux/bttv/Cards	Tue May 28 22:39:19 2002
@@ -15,6 +15,10 @@
 All other cards only differ by additional components as tuners, sound decoders,
 EEPROMs, teletext decoders ...
 
+Unsupported Cards: 
+------------------
+Cards with Zoran (ZR) or Philips (SAA) or ISA are not supported by this driver. 
+
 
 MATRIX Vision
 -------------
@@ -137,20 +141,37 @@
       1851:1850 = Flyvideo 98
       1851:1851 = Flyvideo 98 EZ (capture only)
   2) There is a print on the PCB:
-      LR25       = Flyvideo (Zoran)
-      LR37 Rev.C = Capture only (ZR36120 + SAA7110)
+      LR25       = Flyvideo (Zoran ZR36120, SAA7110A)
+      LR26 Rev.N = Flyvideo II (Bt848)
+           Rev.O = Flyvideo II (Bt878)
+      LR37 Rev.C = Flyvideo EZ (Capture only, ZR36120 + SAA7110)
+      LR38 Rev.A1= Flyvideo II EZ (Bt848 capture only)
       LR50 Rev.Q = Flyvideo 98 (w/eeprom and PCI subsystem ID)
-      LR50 Rev.W = Flyvideo 98 (no eeprom)
+           Rev.W = Flyvideo 98 (no eeprom)
       LR51 Rev.E = Flyvideo 98 EZ (capture only)
       LR90       = Flyvideo 2000 series
-      LR90 Rev.F = Lifetec/Medion LT 9815
+      LR91       = Stereo daughter card for LR90
       LR97       = Flyvideo DVBS
+      LR138 Rev.C= Flyvideo 2000 (SAA7130)
+	        or Flyvideo 3000 (SAA7134) w/Stereo TV
+		   These exist in variations w/FM and w/Remote sometimes denoted
+		   by suffixes "FM" and "R".
+
+      Lifeview.com.tw states (Feb. 2002):
+      "The FlyVideo2000 and FlyVideo2000s product name have renamed to FlyVideo98."
+      Their Bt8x8 cards are listed as discontinued.
+      Flyvideo 2000S was probably sold as Flyvideo 3000 in some contries(Europe?).
+      The new Flyvideo 2000/3000 are SAA7130/SAA7134 based. 
+      Flyvideo 2100/3100 are half-sized cards (for system integrators etc.)
 
   "Flyvideo II" had been the name for the 848 cards, nowadays (in Germany)
   this name is re-used for LR50 Rev.W.
-  The Lifeview website has even more names: Flyvideo III,2100,3000,3100.
+  The Lifeview website mentioned Flyvideo III at some time, but such a card
+  has never been seen. 
   These cards are sold by many OEMs too.
 
+  FlyVideo A2 = LR90 Rev.F (w/Remote, w/o FM, stereo TV by tda9821)
+
 
 Typhoon TV card series:
 -----------------------
@@ -176,6 +197,7 @@
 
 Guillemot
 ---------
+  Maxi-TV PCI (ZR36120)
   Maxi TV Video 2 = LR50 Rev.Q (FI1216MF, PAL BG+SECAM)
   Maxi TV Video 3 = CPH064 (PAL BG + SECAM)
 
@@ -208,3 +230,163 @@
 Genius/Kye
 ----------
    Video Wonder/Genius Internet Video Kit = LR37 Rev.C
+   Video Wonder Pro II (848 or 878) = LR26
+
+Tekram
+------
+   VideoCap C205 (Bt848)
+   VideoCap C210 (Zoran ZR36120 +Philips)
+   CaptureTV M200 (ISA)
+   CaptureTV M205 (Bt848)
+
+Lucky Star
+----------
+   Image World Conference TV = LR50 Rev. Q
+
+Leadtek
+-------
+   WinView 601 (Bt848)
+   WinView 610 (Zoran)
+   WinFast2000
+
+KNC One
+-------
+   TV-Station
+   TV-Station SE (+Software Bundle)
+   TV-Station pro (+TV stereo)
+   TV-Station FM (+Radio)
+   TV-Station RDS (+RDS)
+
+PV951 cards:
+------------
+  These are sold as:
+   Boeder TV-FM Video Capture Card
+   Titanmedia Supervision TV-2400
+   Provideo PV951 TF
+   3DeMon PV951
+   MediaForte TV-Vision PV951
+   Yoko PV951
+
+Highscreen
+----------
+   TV Karte = LR50 Rev.S
+   TV-Boostar = Terratec Terra TV+ Version 1.0 (Bt848, TDA9821) "ceb105.pcb"
+
+Zoltrix
+-------
+   Face To Face TV MAX (Bt848) (PCB "VP-8482 Rev1.3")
+   Genie TV (Bt878) (PCB "VP-8790 Rev 2.1")
+
+AVerMedia
+---------
+   AVer FunTV Lite (ISA, AV3001 chipset)  "M101.C"
+   AVerTV
+   AVerTV Stereo
+   AVerTV Studio (w/FM)
+   AVerMedia TV98 with Remote 
+   AVerMedia TV/FM98 Stereo
+   AVerMedia TVCAM98
+   TVCapture (Bt848)
+   TVPhone (Bt848)
+   TVCapture98 (="AVerMedia TV98" in USA) (Bt878)
+   TVPhone98 (Bt878, w/FM)
+
+   PCB      PCI-ID      Model-Name      Eeprom  Tuner  Sound    Country
+   --------------------------------------------------------------------
+   M1A8-A      --       AVer TV-Phone           FM1216  --
+   M168-T   1461:0003   AVerTV Studio   48:17   FM1216 TDA9840T  D    (1) w/FM w/Remote
+   M168-U   1461:0004   TVCapture98     40:11   FI1216   --      D    w/Remote
+   M168II-B 1461:0003   Medion MD9592   48:16   FM1216 TDA9873H  D    w/FM
+
+   (1) Daughterboard MB68-A with TDA9820T and TDA9840T
+
+Aimslab
+-------
+   Video Highway Xtreme (aka "VHX") (Bt848, FM w/ TEA5757)
+
+IXMicro
+-------
+   IXTV BT848
+   IXTV BT878
+   TurboTV (Bt848)
+
+Lifetec/Medion/Tevion/Aldi
+-------
+   LT9415/MD9415 = LR90 Rev. F
+          MD9592 = Avermedia TVphone98 (PCI_ID=1461:0003), PCB-Rev=M168II-B (w/TDA9873H)
+
+Modular Technologies (www.modulartech.com) UK
+--------------------
+   MM100 PCTV (Bt848)
+   MM205 PCTV (Bt878)
+   MM210 PCTV (Bt878) (Galaxy TV)
+
+Terratec
+--------
+   Terra TV+ Version 1.0 (Bt848), "ceb105.PCB" printed on the PCB, TDA9821
+   Terra TV+ Version 1.1 (Bt878), "LR74 Rev.E" printed on the PCB, TDA9821
+   Terra TValueRadio,             "LR102 Rev.C" printed on the PCB
+   Terra TV/Radio+ Version 1.0,   "80-CP2830100-0" TTTV3 printed on the PCB, i
+				     "CPH010-E83" on the back, SAA6588T, TDA9873H
+   Terra TValue Version BT878,    "80-CP2830110-0 TTTV4" printed on the PCB, 
+				     "CPH011-D83" on back
+   Terra TValue Version 1.0       "ceb105.PCB" (really identical to Terra TV+ Version 1.0)
+
+   LR74 is a newer PCB revision of ceb105 (both incl. connector for Active Radio Upgrade)
+
+
+Technisat
+---------
+   Mediafocus I (ZR36120/ZR36125)
+   Mediafocus II (SAA7146)
+
+Siemens
+-------
+   Multimedia eXtension Board (MXB) (SAA7146, SAA7111)
+
+Stradis
+-------
+   SDM275,SDM250,SDM026,SDM025 (SAA7146, IBMMPEG2): MPEG2 decoder only
+
+Powercolor
+----------
+   MTV878
+   MTV878R w/Remote Control
+   MTV878F w/Remote Control w/FM radio
+
+Pinnacle
+--------
+   Mirovideo PCTV (Bt848)
+   Mirovideo PCTV SE (Bt848)
+   Mirovideo PCTV Pro (Bt848 + Daughterboard)
+   Studio PCTV Rave (Bt878 w/o infrared)
+   Studio PCTV
+   Studio PCTV Pro (Bt878 stereo w/ FM)
+
+   DC1+ (ISA)
+   DC10  (zr36057 + zr36060 + saa7110 + adv7176)
+   DC10+ (zr36067 + zr36060 + saa7110 + adv7176)
+   DC20
+   DC30
+   DC30+ (zr36067 + zr36050 + zr36016 + vpx3220 + adv7176)
+
+Lenco
+-----
+   MXR-9565 (=Technisat Mediafocus?)
+   MXR-9571 (Bt848)
+   MXR-9575
+   MXR-9477 (Bt878)
+   MXTV-9578CP (= Prolink PV-BT878P+4E)
+
+Iomega
+------
+   Buz (Zoran zr36067 + zr36060 + SAA7111 + SAA7185)
+
+LML
+---
+   LML33 (zr36067 + zr36060 + bt819+ bt856)
+
+Grandtec
+--------
+   Grand Video Capture (Bt848)
+   Multi Capture Card  (Bt878)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/video4linux/bttv/Insmod-options linux/Documentation/video4linux/bttv/Insmod-options
--- linux.orig/Documentation/video4linux/bttv/Insmod-options	Wed Oct 17 21:19:20 2001
+++ linux/Documentation/video4linux/bttv/Insmod-options	Tue May 28 22:39:17 2002
@@ -28,7 +28,7 @@
 				default is 0 (off).
 		irq_debug=0/1	irq handler debug messages.
 				default is 0 (off).
-		gbuffers=2-64	number of capture buffers for mmap'ed capture.
+		gbuffers=2-32	number of capture buffers for mmap'ed capture.
 				default is 2.
 		gbufsize=	size of capture buffers. default and
 				maximum value is 0x208000 (~2MB)
@@ -38,6 +38,13 @@
 				push used by bttv.  bttv will disable overlay
 				by default on this hardware to avoid crashes.
 				With this insmod option you can override this.
+		automute=0/1	Automatically mutes the sound if there is
+				no TV signal, on by default.  You might try
+				to disable this if you have bad input signal
+				quality which leading to unwanted sound
+				dropouts.
+		chroma_agc=0/1	AGC of chroma signal, off by default.
+		adc_crush=0/1	Luminance ADC crush, on by default.
 
 		bttv_gpio=0/1
 		gpiomask=
@@ -89,6 +96,8 @@
 	insmod args for tda9874a:
 		tda9874a_SIF=1/2	select sound IF input pin (1 or 2)
 					(default is pin 1)
+		tda9874a_AMSEL=0/1	auto-mute select for NICAM (default=0)
+					Please read note 3 below!
 		tda9874a_STD=n		select TV sound standard (0..8):
 					0 - A2, B/G
 					1 - A2, M (Korea)
@@ -100,11 +109,20 @@
 					7 - NICAM, D/K (default)
 					8 - NICAM, L
 
-	Note: tda9874a is very similar to tda9874 (without 'A'-suffix), but
-	this driver will not work for the latter device (will not load).
-	Note: tda9874a and tda9875 (which is supported separately by
+	Note 1: tda9874a supports both tda9874h (old) and tda9874a (new) chips.
+	Note 2: tda9874h/a and tda9875 (which is supported separately by
 	tda9875.o) use the same i2c address so both modules should not be
 	used at the same time.
+	Note 3: Using tda9874a_AMSEL option depends on your TV card design!
+		AMSEL=0: auto-mute will switch between NICAM sound
+			 and the sound on 1st carrier (i.e. FM mono or AM).
+		AMSEL=1: auto-mute will switch between NICAM sound
+			 and the analog mono input (MONOIN pin).
+	If tda9874a decoder on your card has MONOIN pin not connected, then
+	use only tda9874_AMSEL=0 or don't specify this option at all.
+	For example:
+	  card=65 (FlyVideo 2000S) - set AMSEL=1 or AMSEL=0
+	  card=72 (Prolink PV-BT878P rev.9B) - set AMSEL=0 only
 
 msp3400.o
 	The driver for the msp34xx sound processor chips. If you have a
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/video4linux/bttv/README.freeze linux/Documentation/video4linux/bttv/README.freeze
--- linux.orig/Documentation/video4linux/bttv/README.freeze	Thu Jan  1 00:00:00 1970
+++ linux/Documentation/video4linux/bttv/README.freeze	Tue May 28 22:39:20 2002
@@ -0,0 +1,65 @@
+
+If the box freezes hard with bttv ...
+=====================================
+
+It might be a bttv driver bug.  It also might be bad hardware.  It also
+might be something else ...
+
+Just mailing me "bttv freezes" isn't going to help much.  This README
+has a few hints how you can help to pin down the problem.
+
+
+bttv bugs
+---------
+
+If some version works and another doesn't it is likely to be a driver
+bug.  It is very helpful if you can tell where exactly it broke
+(i.e. the last working and the first broken version).
+
+With a hard freeze you probably doesn't find anything in the logfiles.
+The only way to capture any kernel messages is to hook up a serial
+console and let some terminal application log the messages.  /me uses
+screen.  See Documentation/serial-console.txt for details on setting
+up a serial console.
+
+Read Documentation/oops-tracing.txt to learn how to get any useful
+information out of a register+stack dump printed by the kernel on
+protection faults (so-called "kernel oops").
+
+If you run into some kind of deadlock, you can try to dump a call trace
+for each process using sysrq-t (see Documentation/sysrq.txt).  ksymoops
+will translate these dumps into kernel symbols too.  This way it is
+possible to figure where *exactly* some process in "D" state is stuck.
+
+I've seen reports that bttv 0.7.x crashes whereas 0.8.x works rock solid
+for some people.  Thus probably a small buglet left somewhere in bttv
+0.7.x.  I have no idea where exactly, it works stable for me and alot of
+other people.  But in case you have problems with the 0.7.x versions you
+can give 0.8.x a try ...
+
+
+hardware bugs
+-------------
+
+Some hardware can't deal with PCI-PCI transfers (i.e. grabber => vga).
+Sometimes problems show up with bttv just because of the high load on
+the PCI bus. The bt848/878 chips have a few workarounds for known
+incompatibilities, see README.quirks.
+
+Some mainboard have problems to deal correctly with multiple devices
+doing DMA at the same time.  bttv + ide seems to cause this sometimes,
+if this is the case you likely see freezes only with video and hard disk
+access at the same time.  Updating the IDE driver to get the latest and
+greatest workarounds for hardware bugs might fix these problems.
+
+
+other
+-----
+
+IRQ sharing is known to cause problems in some cases.  It works just
+fine in theory and many configurations.  Neverless it might be worth a
+try to shuffle around the PCI cards to give bttv another IRQ or make
+it share the IRQ with some other piece of hardware.  IRQ sharing with
+VGA cards seems to cause trouble sometimes.  I've also seen funny
+effects with bttv sharing the IRQ with the ACPI bridge (and
+apci-enabled kernel).
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/video4linux/bttv/Sound-FAQ linux/Documentation/video4linux/bttv/Sound-FAQ
--- linux.orig/Documentation/video4linux/bttv/Sound-FAQ	Wed Oct 17 21:19:20 2001
+++ linux/Documentation/video4linux/bttv/Sound-FAQ	Tue May 28 22:39:28 2002
@@ -62,7 +62,7 @@
 {
 	[ ... ]
         u32 gpiomask;
-        u32 audiomux[5];  /* audio mux: tuner, radio, external, internal, mute */
+        u32 audiomux[6]; /* Tuner, Radio, external, internal, mute, stereo */
 };
 
 gpiomask specifies which pins are used to control the audio mux chip.
@@ -127,6 +127,9 @@
 *_modulename    - hint whenever some card needs this or that audio
                   module loaded to work properly.
 has_radio	- whenever this TV card has a radio tuner.
+no_msp34xx	- "1" disables loading of msp3400.o module
+no_tda9875	- "1" disables loading of tda9875.o module 
+needs_tvaudio	- set to "1" to load tvaudio.o module 
 
 If some config item is specified both from the tvcards array and as
 insmod option, the insmod option takes precedence.
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/video4linux/meye.txt linux/Documentation/video4linux/meye.txt
--- linux.orig/Documentation/video4linux/meye.txt	Thu Oct 11 16:04:57 2001
+++ linux/Documentation/video4linux/meye.txt	Tue May 28 22:39:19 2002
@@ -15,8 +15,16 @@
 
 MJPEG hardware grabbing is supported via a private API (see below).
 
-Module options:
+Driver options:
 ---------------
+
+Several options can be passed to the meye driver, either by adding them
+to /etc/modules.conf file, when the driver is compiled as a module, or
+by adding the following to the kernel command line (in your bootloader):
+
+	meye=gbuffers[,gbufsize[,video_nr]]
+
+where:
 
 	gbuffers:	number of capture buffers, default is 2 (32 max)
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Documentation/watchdog-api.txt linux/Documentation/watchdog-api.txt
--- linux.orig/Documentation/watchdog-api.txt	Thu Jan  1 00:00:00 1970
+++ linux/Documentation/watchdog-api.txt	Tue May 28 22:39:29 2002
@@ -0,0 +1,390 @@
+The Linux Watchdog driver API.
+
+Copyright 2002 Christer Weingel <wingel@nano-system.com>
+
+Some parts of this document are copied verbatim from the sbc60xxwdt
+driver which is (c) Copyright 2000 Jakob Oestergaard <jakob@ostenfeld.dk>
+
+This document describes the state of the Linux 2.4.18 kernel.
+
+Introduction:
+
+A Watchdog Timer (WDT) is a hardware circuit that can reset the
+computer system in case of a software fault.  You probably knew that
+already.
+
+Usually a userspace daemon will notify the kernel watchdog driver via the
+/dev/watchdog special device file that userspace is still alive, at
+regular intervals.  When such a notification occurs, the driver will
+usually tell the hardware watchdog that everything is in order, and
+that the watchdog should wait for yet another little while to reset
+the system.  If userspace fails (RAM error, kernel bug, whatever), the
+notifications cease to occur, and the hardware watchdog will reset the
+system (causing a reboot) after the timeout occurs.
+
+The Linux watchdog API is a rather AD hoc construction and different
+drivers implement different, and sometimes incompatible, parts of it.
+This file is an attempt to document the existing usage and allow
+future driver writers to use it as a reference.
+
+The simplest API:
+
+All drivers support the basic mode of operation, where the watchdog
+activates as soon as /dev/watchdog is opened and will reboot unless
+the watchdog is pinged within a certain time, this time is called the
+timeout or margin.  The simplest way to ping the watchdog is to write
+some data to the device.  So a very simple watchdog daemon would look
+like this:
+
+int main(int argc, const char *argv[]) {
+	int fd=open("/dev/watchdog",O_WRONLY);
+	if (fd==-1) {
+		perror("watchdog");
+		exit(1);
+	}
+	while(1) {
+		write(fd, "\0", 1);
+		sleep(10);
+	}
+}
+
+A more advanced driver could for example check that a HTTP server is
+still responding before doing the write call to ping the watchdog.
+
+When the device is closed, the watchdog is disabled.  This is not
+always such a good idea, since if there is a bug in the watchdog
+daemon and it crashes the system will not reboot.  Because of this,
+some of the drivers support the configuration option "Disable watchdog
+shutdown on close", CONFIG_WATCHDOG_NOWAYOUT.  If it is set to Y when
+compiling the kernel, there is no way of disabling the watchdog once
+it has been started.  So, if the watchdog dameon crashes, the system
+will reboot after the timeout has passed.
+
+Some other drivers will not disable the watchdog, unless a specific
+magic character 'V' has been sent /dev/watchdog just before closing
+the file.  If the userspace daemon closes the file without sending
+this special character, the driver will assume that the daemon (and
+userspace in general) died, and will stop pinging the watchdog without
+disabling it first.  This will then cause a reboot.
+
+The ioctl API:
+
+All conforming drivers also support an ioctl API.
+
+Pinging the watchdog using an ioctl:
+
+All drivers that have an ioctl interface support at least one ioctl,
+KEEPALIVE.  This ioctl does exactly the same thing as a write to the
+watchdog device, so the main loop in the above program could be
+replaced with:
+
+	while (1) {
+		ioctl(fd, WDIOC_KEEPALIVE, 0);
+		sleep(10);
+	}
+
+the argument to the ioctl is ignored.
+
+Setting and getting the timeout:
+
+For some drivers it is possible to modify the watchdog timeout on the
+fly with the SETTIMEOUT ioctl, those drivers have the WDIOF_SETTIMEOUT
+flag set in their option field.  The argument is an integer
+representing the timeout in seconds.  The driver returns the real
+timeout used in the same variable, and this timeout might differ from
+the requested one due to limitation of the hardware.
+
+    int timeout = 45;
+    ioctl(fd, WDIOC_SETTIMEOUT, &timeout);
+    printf("The timeout was set to %d seconds\n", timeout);
+
+This example might actually print "The timeout was set to 60 seconds"
+if the device has a granularity of minutes for its timeout.
+
+Starting with the Linux 2.4.18 kernel, it is possible to query the
+current timeout using the GETTIMEOUT ioctl.
+
+    ioctl(fd, WDIOC_GETTIMEOUT, &timeout);
+    printf("The timeout was is %d seconds\n", timeout);
+
+Envinronmental monitoring:
+
+All watchdog drivers are required return more information about the system,
+some do temperature, fan and power level monitoring, some can tell you
+the reason for the last reboot of the system.  The GETSUPPORT ioctl is
+available to ask what the device can do:
+
+	struct watchdog_info ident;
+	ioctl(fd, WDIOC_GETSUPPORT, &ident);
+
+the fields returned in the ident struct are:
+
+        identity		a string identifying the watchdog driver
+	firmware_version	the firmware version of the card if available
+	options			a flags describing what the device supports
+
+the options field can have the following bits set, and describes what
+kind of information that the GET_STATUS and GET_BOOT_STATUS ioctls can
+return.   [FIXME -- Is this correct?]
+
+	WDIOF_OVERHEAT		Reset due to CPU overheat
+
+The machine was last rebooted by the watchdog because the thermal limit was
+exceeded
+
+	WDIOF_FANFAULT		Fan failed
+
+A system fan monitored by the watchdog card has failed
+
+	WDIOF_EXTERN1		External relay 1
+
+External monitoring relay/source 1 was triggered. Controllers intended for
+real world applications include external monitoring pins that will trigger
+a reset.
+
+	WDIOF_EXTERN2		External relay 2
+
+External monitoring relay/source 2 was triggered
+
+	WDIOF_POWERUNDER	Power bad/power fault
+
+The machine is showing an undervoltage status
+
+	WDIOF_CARDRESET		Card previously reset the CPU
+
+The last reboot was caused by the watchdog card
+
+	WDIOF_POWEROVER		Power over voltage
+
+The machine is showing an overvoltage status. Note that if one level is
+under and one over both bits will be set - this may seem odd but makes
+sense.
+
+	WDIOF_KEEPALIVEPING	Keep alive ping reply
+
+The watchdog saw a keepalive ping since it was last queried.
+
+	WDIOF_SETTIMEOUT	Can set/get the timeout
+
+
+For those drivers that return any bits set in the option field, the
+GETSTATUS and GETBOOTSTATUS ioctls can be used to ask for the current
+status, and the status at the last reboot, respectively.  
+
+    int flags;
+    ioctl(fd, WDIOC_GETSTATUS, &flags);
+
+    or
+
+    ioctl(fd, WDIOC_GETBOOTSTATUS, &flags);
+
+Note that not all devices support these two calls, and some only
+support the GETBOOTSTATUS call.
+
+Some drivers can measure the temperature using the GETTEMP ioctl.  The
+returned value is the temperature in degrees farenheit.
+
+    int temperature;
+    ioctl(fd, WDIOC_GETTEMP, &temperature);
+
+Finally the SETOPTIONS ioctl can be used to control some aspects of
+the cards operation; right now the pcwd driver is the only one
+supporting thiss ioctl.
+
+    int options = 0;
+    ioctl(fd, WDIOC_SETOPTIONS, options);
+
+The following options are available:
+
+	WDIOS_DISABLECARD	Turn off the watchdog timer
+	WDIOS_ENABLECARD	Turn on the watchdog timer
+	WDIOS_TEMPPANIC		Kernel panic on temperature trip
+
+[FIXME -- better explanations]
+
+Implementations in the current drivers in the kernel tree:
+
+Here I have tried to summarize what the different drivers support and
+where they do strange things compared to the other drivers.
+
+acquirewdt.c -- Acquire Single Board Computer
+
+	This driver has a hardcoded timeout of 1 minute
+
+	Supports CONFIG_WATCHDOG_NOWAYOUT
+
+	GETSUPPORT returns KEEPALIVEPING.  GETSTATUS will return 1 if
+	the device is open, 0 if not.  [FIXME -- isn't this rather
+	silly?  To be able to use the ioctl, the device must be open
+	and so GETSTATUS will always return 1].
+
+advantechwdt.c -- Advantech Single Board Computer
+
+	Timeout that defaults to 60 seconds, supports SETTIMEOUT.
+
+	Supports CONFIG_WATCHDOG_NOWAYOUT
+
+	GETSUPPORT returns WDIOF_KEEPALIVEPING and WDIOF_SETTIMEOUT.
+	The GETSTATUS call returns if the device is open or not.
+	[FIXME -- silliness again?]
+	
+eurotechwdt.c -- Eurotech CPU-1220/1410
+
+	The timeout can be set using the SETTIMEOUT ioctl and defaults
+	to 60 seconds.
+
+	Also has a module parameter "ev", event type which controls
+	what should happen on a timeout, the string "int" or anything
+	else that causes a reboot.  [FIXME -- better description]
+
+	Supports CONFIG_WATCHDOG_NOWAYOUT
+
+	GETSUPPORT returns CARDRESET and WDIOF_SETTIMEOUT but
+	GETSTATUS is not supported and GETBOOTSTATUS just returns 0.
+
+i810-tco.c -- Intel 810 chipset
+
+	Also has support for a lot of other i8x0 stuff, but the
+	watchdog is one of the things.
+
+	The timeout is set using the module parameter "i810_margin",
+	which is in steps of 0.6 seconds where 2<i810_margin<64.  The
+	driver supports the SETTIMEOUT ioctl.
+
+	Supports CONFIG_WATCHDOG_NOWAYOUT.
+
+	GETSUPPORT returns WDIOF_SETTIMEOUT.  The GETSTATUS call
+	returns some kind of timer value which ist not compatible with
+	the other drivers.  GETBOOT status returns some kind of
+	hardware specific boot status.  [FIXME -- describe this]
+
+ib700wdt.c -- IB700 Single Board Computer
+
+	Default timeout of 30 seconds and the timeout is settable
+	using the SETTIMEOUT ioctl.  Note that only a few timeout
+	values are supported.
+
+	Supports CONFIG_WATCHDOG_NOWAYOUT
+
+	GETSUPPORT returns WDIOF_KEEPALIVEPING and WDIOF_SETTIMEOUT.
+	The GETSTATUS call returns if the device is open or not.
+	[FIXME -- silliness again?]
+
+machzwd.c -- MachZ ZF-Logic
+
+	Hardcoded timeout of 10 seconds
+
+	Has a module parameter "action" that controls what happens
+	when the timeout runs out which can be 0 = RESET (default), 
+	1 = SMI, 2 = NMI, 3 = SCI.
+
+	Supports CONFIG_WATCHDOG_NOWAYOUT and the the magic character
+	'V' close handling.
+
+	GETSUPPORT returns WDIOF_KEEPALIVEPING, and the GETSTATUS call
+	returns if the device is open or not.  [FIXME -- silliness
+	again?]
+
+mixcomwd.c -- MixCom Watchdog
+
+	[FIXME -- I'm unable to tell what the timeout is]
+
+	Supports CONFIG_WATCHDOG_NOWAYOUT
+
+	GETSUPPORT returns WDIOF_KEEPALIVEPING, GETSTATUS returns if
+	the device is opened or not [FIXME -- I'm not really sure how
+	this works, there seems to be some magic connected to
+	CONFIG_WATCHDOG_NOWAYOUT]
+
+pcwd.c -- Berkshire PC Watchdog
+
+	Hardcoded timeout of 1.5 seconds
+
+	Supports CONFIG_WATCHDOG_NOWAYOUT
+
+	GETSUPPORT returns WDIOF_OVERHEAT|WDIOF_CARDRESET and both
+	GETSTATUS and GETBOOTSTATUS return something useful.
+
+	The SETOPTIONS call can be used to enable and disable the card
+	and to ask the driver to call panic if the system overheats.
+
+sbc60xxwdt.c -- 60xx Single Board Computer
+
+	Hardcoded timeout of 10 seconds
+
+	Does not support CONFIG_WATCHDOG_NOWAYOUT, but has the magic
+	character 'V' close handling.
+
+	No bits set in GETSUPPORT
+
+scx200.c -- National SCx200 CPUs
+
+	Not in the kernel yet.
+
+	The timeout is set using a module parameter "margin" which
+	defaults to 60 seconds.  The timeout can also be set using
+	SETTIMEOUT and read using GETTIMEOUT.
+
+	Supports a module parameter "nowayout" that is initialized
+	with the value of CONFIG_WATCHDOG_NOWAYOUT.  Also supports the
+	magic character 'V' handling.
+
+shwdt.c -- SuperH 3/4 processors
+
+	[FIXME -- I'm unable to tell what the timeout is]
+
+	Supports CONFIG_WATCHDOG_NOWAYOUT
+
+	GETSUPPORT returns WDIOF_KEEPALIVEPING, and the GETSTATUS call
+	returns if the device is open or not.  [FIXME -- silliness
+	again?]
+
+softdog.c -- Software watchdog
+
+	The timeout is set with the module parameter "soft_margin"
+	which defaults to 60 seconds, the timeout is also settable
+	using the SETTIMEOUT ioctl.
+
+	Supports CONFIG_WATCHDOG_NOWAYOUT
+
+	WDIOF_SETTIMEOUT bit set in GETSUPPORT
+
+w83877f_wdt.c -- W83877F Computer
+
+	Hardcoded timeout of 30 seconds
+
+	Does not support CONFIG_WATCHDOG_NOWAYOUT, but has the magic
+	character 'V' close handling.
+
+	No bits set in GETSUPPORT
+
+wdt.c -- ICS WDT500/501 ISA and
+wdt_pci.c -- ICS WDT500/501 PCI
+
+	Default timeout of 60 seconds.  The timeout is also settable
+        using the SETTIMEOUT ioctl.
+
+	Supports CONFIG_WATCHDOG_NOWAYOUT
+
+	GETSUPPORT returns with bits set depending on the actual
+	card. The WDT501 supports a lot of external monitoring, the
+	WDT500 much less.
+
+wdt285.c -- Footbridge watchdog
+
+	The timeout is set with the module parameter "soft_margin"
+	which defaults to 60 seconds.  The timeout is also settable
+	using the SETTIMEOUT ioctl.
+
+	Does not support CONFIG_WATCHDOG_NOWAYOUT
+
+	WDIOF_SETTIMEOUT bit set in GETSUPPORT
+
+wdt977.c -- Netwinder W83977AF chip
+
+	Hardcoded timeout of 3 minutes
+
+	Supports CONFIG_WATCHDOG_NOWAYOUT
+
+	Does not support any ioctls at all.
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/MAINTAINERS linux/MAINTAINERS
--- linux.orig/MAINTAINERS	Mon Feb 25 19:37:52 2002
+++ linux/MAINTAINERS	Tue May 28 22:39:14 2002
@@ -69,6 +69,14 @@
 			it has been replaced by a better system and you
 			should be using that.
 
+3C359 NETWORK DRIVER
+P:	Mike Phillips
+M:	mikep@linuxtr.net
+L:	linux-net@vger.rutgers.edu
+L:	linux-tr@linuxtr.net
+W:	http://www.linuxtr.net
+S:	Maintained
+
 3C501 NETWORK DRIVER
 P:	Alan Cox
 M:	alan@the.3c501.cabal.tm
@@ -260,9 +268,9 @@
 
 BTTV VIDEO4LINUX DRIVER
 P:	Gerd Knorr
-M:	kraxel@goldbach.in-berlin.de
+M:	kraxel@bytesex.org
 L:	video4linux-list@redhat.com
-W:	http://me.in-berlin.de/~kraxel/bttv.html
+W:	http://bytesex.org/bttv/
 S:	Maintained
 
 BUSLOGIC SCSI DRIVER
@@ -544,14 +552,12 @@
 S:      Maintained
 
 EXT2 FILE SYSTEM
-P:	Remy Card
-M:	Remy.Card@linux.org
-L:	linux-kernel@vger.kernel.org
+L:	ext2-devel@lists.sourceforge.net
 S:	Maintained
 
 EXT3 FILE SYSTEM
-P:	Remy Card, Stephen Tweedie
-M:	sct@redhat.com, akpm@zip.com.au, adilger@turbolinux.com
+P:	Stephen Tweedie, Andrew Morton
+M:	sct@redhat.com, akpm@zip.com.au, adilger@clusterfs.com
 L:	ext3-users@redhat.com
 S:	Maintained
 
@@ -667,7 +673,7 @@
 
 i386 BOOT CODE
 P:	Riley H. Williams
-M:	rhw@memalpha.cx
+M:	Riley@Williams.Name
 L:	Linux-Kernel@vger.kernel.org
 S:	Maintained
 
@@ -706,12 +712,12 @@
 IDE DRIVER [GENERAL]
 P:	Andre Hedrick
 M:	andre@linux-ide.org
-M:	andre@aslab.com
-M:	andre@suse.com
+M:	andre@linuxdiskcert.org
 L:	linux-kernel@vger.kernel.org
 W:	http://www.kernel.org/pub/linux/kernel/people/hedrick/
 W:	http://www.linux-ide.org/
-S:	Supported
+W:	http://www.linuxdiskcert.org/
+S:	Maintained
 
 IDE/ATAPI CDROM DRIVER
 P:	Jens Axboe
@@ -734,16 +740,12 @@
 S:	Maintained
 
 IEEE 1394 SUBSYSTEM
-P:	Andreas Bombe
-M:	andreas.bombe@munich.netsurf.de
+P:	Ben Collins
+M:	bcollins@debian.org
 L:	linux1394-devel@lists.sourceforge.net
 W:	http://linux1394.sourceforge.net/
 S:	Maintained
 
-IEEE 1394 AIC5800 DRIVER
-L:	linux1394-devel@lists.sourceforge.net
-S:	Orphan
-
 IEEE 1394 OHCI DRIVER
 P:	Ben Collins
 M:	bcollins@debian.org
@@ -791,6 +793,12 @@
 L:      intermezzo-discuss@lists.sourceforge.net
 S:      Maintained
 
+IOC3 DRIVER
+P:	Ralf Baechle
+M:	ralf@oss.sgi.com
+L:	linux-mips@oss.sgi.com
+S:	Maintained
+
 IP MASQUERADING:
 P:	Juanjo Ciarlante
 M:	jjciarla@raiz.uncu.edu.ar
@@ -849,7 +857,7 @@
 M:	vojtech@suse.cz
 L:	linux-joystick@atrey.karlin.mff.cuni.cz
 W:	http://www.suse.cz/development/joystick/
-S:	Supported
+S:	Maintained
 
 KERNEL AUTOMOUNTER (AUTOFS)
 P:	H. Peter Anvin
@@ -918,6 +926,13 @@
 L:	linuxppc-dev@lists.linuxppc.org
 S:	Maintained
 
+LINUX FOR 64BIT POWERPC
+P:	David Engebretsen
+M:	engebret@us.ibm.com
+W:	http://linuxppc64.org
+L:	linuxppc64-dev@lists.linuxppc.org
+S:	Supported
+
 LOGICAL DISK MANAGER SUPPORT (LDM, Windows 2000/XP Dynamic Disks)
 P:	Richard Russon (FlatCap)
 M:	ldm@flatcap.org
@@ -1156,6 +1171,12 @@
 L:	linux-sound@vger.kernel.org
 S:	Maintained
 
+ORINOCO DRIVER
+P:	David Gibson
+M:	hermes@gibson.dropbear.id.au
+W:	http://www.ozlabs.org/people/dgibson/dldwd
+S:	Maintained
+
 PARALLEL PORT SUPPORT
 P:	Phil Blundell
 M:	Philip.Blundell@pobox.com
@@ -1183,8 +1204,10 @@
 S:	Maintained
 
 PCI ID DATABASE
-P:	Jens Maurer
-M:	jmaurer@cck.uni-kl.de
+P:	Martin Mares
+M:	mj@ucw.cz
+L:	pciids-devel@lists.sourceforge.net
+W:	http://pciids.sourceforge.net/
 S:	Maintained
 
 PCI SOUND DRIVERS (ES1370, ES1371 and SONICVIBES)
@@ -1224,6 +1247,20 @@
 L:	linux-net@vger.kernel.org
 S:	Maintained
 
+PERMEDIA 3 FRAMEBUFFER DRIVER
+P:	Romain Dolbeau
+M:	dolbeau@irisa.fr
+L:	linux-fbdev-devel@lists.sourceforge.net
+W:	http://www.irisa.fr/prive/dolbeau/pm3fb/pm3fb.html
+S:	Maintained
+
+PHILIPS NINO PALM PC
+P:	Steven Hill
+M:	sjhill@realitydiluted.com
+L:	linux-mips@oss.sgi.com
+W:	http://www.realitydiluted.com/projects/nino
+S:	Maintained
+
 PNP SUPPORT
 P:	Tom Lees
 M:	tom@lpsg.demon.co.uk
@@ -1304,6 +1341,12 @@
 L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
+RME96XX MULTICHANNEL SOUND DRIVER
+P:      Guenter Geiger
+M:      geiger@epy.co.at  
+L:      linux-kernel@vger.kernel.org
+S:      Maintained
+
 RTLINUX  REALTIME  LINUX
 P:	Victor Yodaiken
 M:	yodaiken@fsmlabs.com
@@ -1331,6 +1374,11 @@
 L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
+SC1200 WDT DRIVER
+P:      Zwane Mwaikambo
+M:      zwane@commfireservices.com
+S:      Maintained
+
 SCSI CDROM DRIVER
 P:	Jens Axboe
 M:	axboe@suse.de
@@ -1362,6 +1410,13 @@
 M:	mingo@redhat.com
 S:	Maintained
 
+SIS 5513 IDE CONTROLLER DRIVER
+P:      Lionel Bouton
+M:      Lionel.Bouton@inet6.fr
+W:      http://inet6.dyn.dhs.org/sponsoring/sis5513/index.html
+W:      http://gyver.homeip.net/sis5513/index.html
+S:      Maintained
+
 SIS 900/7016 FAST ETHERNET DRIVER
 P:	Ollie Lho
 M:	ollie@sis.com.tw
@@ -1412,8 +1467,6 @@
 M:	anton@samba.org
 L:	sparclinux@vger.kernel.org
 L:	ultralinux@vger.kernel.org
-W:	http://ultra.linux.cz
-W:	http://www.geog.ubc.ca/s_linux.html
 S:	Maintained
 
 SPECIALIX IO8+ MULTIPORT SERIAL CARD DRIVER
@@ -1477,13 +1530,18 @@
 M:	hch@infradead.org
 S:	Maintained
 
+TIEMAN VOYAGER USB BRAILLE DISPLAY DRIVER
+P:	Stephane Dalton
+M:	sdalton@videotron.ca
+P:	Stéphane Doyon
+M:	s.doyon@videotron.ca
+S:	Maintained
+
 TLAN NETWORK DRIVER
-P:	Torben Mathiasen
-M:	torben.mathiasen@compaq.com
-M:	torben@kernel.dk
-L:	tlan@vuser.vu.union.edu
-L:	linux-net@vger.kernel.org
-W:	http://tlan.kernel.dk
+P:	Samuel Chessman
+M:	chessman@tux.org
+L:	tlan-devel@lists.sourceforge.net
+W:	http://sourceforge.net/projects/tlan/
 S:	Maintained
 
 TOKEN-RING NETWORK DRIVER
@@ -1562,7 +1620,14 @@
 M:	vojtech@suse.cz
 L:	linux-usb-users@lists.sourceforge.net
 L:	linux-usb-devel@lists.sourceforge.net
-S:	Supported
+S:	Maintained
+
+USB AUERSWALD DRIVER
+P:	Wolfgang Muees
+M:	wmues@nexgo.de
+L:	linux-usb-users@lists.sourceforge.net
+L:	linux-usb-devel@lists.sourceforge.net
+S:	Maintained
 
 USB BLUETOOTH DRIVER
 P:	Greg Kroah-Hartman
@@ -1579,13 +1644,19 @@
 L:	linux-usb-devel@lists.sourceforge.net
 S:	Maintained
 
+USB EHCI DRIVER
+P:	David Brownell
+M:	dbrownell@users.sourceforge.net
+L:	linux-usb-devel@lists.sourceforge.net
+S:	Maintained
+
 USB HID/HIDBP/INPUT DRIVERS
 P:	Vojtech Pavlik
 M:	vojtech@suse.cz
 L:	linux-usb-users@lists.sourceforge.net
 L:	linux-usb-devel@lists.sourceforge.net
 W:	http://www.suse.cz/development/input/
-S:	Supported
+S:	Maintained
 
 USB HUB
 P:	Johannes Erdfelt
@@ -1595,8 +1666,8 @@
 S:	Maintained
 
 USB KAWASAKI LSI DRIVER
-P:	Brad Hards
-M:	bradh@frogmouth.net
+P:	Oliver Neukum
+M:	drivers@neukum.org
 L:	linux-usb-users@lists.sourceforge.net
 L:	linux-usb-devel@lists.sourceforge.net
 S:	Maintained
@@ -1626,7 +1697,7 @@
 
 USB PEGASUS DRIVER
 P:	Petko Manolov
-M:	petkan@dce.bg
+M:	petkan@users.sourceforge.net
 L:	linux-usb-users@lists.sourceforge.net
 L:	linux-usb-devel@lists.sourceforge.net
 S:	Maintained
@@ -1636,7 +1707,14 @@
 M:	vojtech@suse.cz
 L:	linux-usb-users@lists.sourceforge.net
 L:	linux-usb-devel@lists.sourceforge.net
-S:	Supported
+S:	Maintained
+
+USB RTL8150 DRIVER
+P:	Petko Manolov
+M:	petkan@users.sourceforge.net
+L:	linux-usb-users@lists.sourceforge.net
+L:	linux-usb-devel@lists.sourceforge.net
+S:	Maintained
 
 USB SE401 DRIVER
 P:	Jeroen Vreeken
@@ -1684,12 +1762,12 @@
 S:	Maintained
 
 USB SERIAL KEYSPAN DRIVER
-P:	Hugh Blemings
-M:	hugh@misc.nu
+P:	Greg Kroah-Hartman
+M:	greg@kroah.com
 L:	linux-usb-users@lists.sourceforge.net
 L:	linux-usb-devel@lists.sourceforge.net
+W:	http://www.kroah.com/linux/
 S:	Maintained
-W:	http://misc.nu/hugh/keyspan/
 
 USB SUBSYSTEM
 P:	Greg Kroah-Hartman
@@ -1707,6 +1785,12 @@
 W:	http://usb.in.tum.de
 S:	Maintained
 	
+USB "USBNET" DRIVER
+P:	David Brownell
+M:	dbrownell@users.sourceforge.net
+L:	linux-usb-devel@lists.sourceforge.net
+S:	Maintained
+
 VFAT FILESYSTEM:
 P:	Gordon Chaffee
 M:	chaffee@cs.berkeley.edu
@@ -1727,10 +1811,9 @@
 S:	Maintained
 
 VIDEO FOR LINUX
-P:	Alan Cox
-M:	Alan.Cox@linux.org
-W:	http://roadrunner.swansea.linux.org.uk/v4l.shtml
-S:	Maintained for 2.2 only
+P:	Gerd Knorr
+M:	kraxel@bytesex.org
+S:	Maintained
 
 WAN ROUTER & SANGOMA WANPIPE DRIVERS & API (X.25, FRAME RELAY, PPP, CISCO HDLC)
 P:     Nenad Corbic
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Makefile linux/Makefile
--- linux.orig/Makefile	Mon Feb 25 19:37:52 2002
+++ linux/Makefile	Tue May 28 22:39:16 2002
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
-SUBLEVEL = 18
-EXTRAVERSION =
+SUBLEVEL = 19
+EXTRAVERSION = -pre9
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
@@ -14,7 +14,7 @@
 TOPDIR	:= $(shell /bin/pwd)
 
 HPATH   	= $(TOPDIR)/include
-FINDHPATH	= $(HPATH)/asm $(HPATH)/linux $(HPATH)/scsi $(HPATH)/net
+FINDHPATH	= $(HPATH)/asm $(HPATH)/linux $(HPATH)/scsi $(HPATH)/net $(HPATH)/math-emu
 
 HOSTCC  	= gcc
 HOSTCFLAGS	= -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
@@ -89,7 +89,10 @@
 CPPFLAGS := -D__KERNEL__ -I$(HPATH)
 
 CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \
-	  -fomit-frame-pointer -fno-strict-aliasing -fno-common
+	  -fno-strict-aliasing -fno-common
+ifndef CONFIG_FRAME_POINTER
+CFLAGS += -fomit-frame-pointer
+endif
 AFLAGS := -D__ASSEMBLY__ $(CPPFLAGS)
 
 #
@@ -140,9 +143,8 @@
 DRIVERS-$(CONFIG_DRM_NEW) += drivers/char/drm/drm.o
 DRIVERS-$(CONFIG_DRM_OLD) += drivers/char/drm-4.0/drm.o
 DRIVERS-$(CONFIG_NUBUS) += drivers/nubus/nubus.a
-DRIVERS-$(CONFIG_ISDN) += drivers/isdn/isdn.a
 DRIVERS-$(CONFIG_NET_FC) += drivers/net/fc/fc.o
-DRIVERS-$(CONFIG_APPLETALK) += drivers/net/appletalk/appletalk.o
+DRIVERS-$(CONFIG_DEV_APPLETALK) += drivers/net/appletalk/appletalk.o
 DRIVERS-$(CONFIG_TR) += drivers/net/tokenring/tr.o
 DRIVERS-$(CONFIG_WAN) += drivers/net/wan/wan.o
 DRIVERS-$(CONFIG_ARCNET) += drivers/net/arcnet/arcnetdrv.o
@@ -168,7 +170,7 @@
 DRIVERS-$(CONFIG_SBUS) += drivers/sbus/sbus_all.o
 DRIVERS-$(CONFIG_ZORRO) += drivers/zorro/driver.o
 DRIVERS-$(CONFIG_FC4) += drivers/fc4/fc4.a
-DRIVERS-$(CONFIG_ALL_PPC) += drivers/macintosh/macintosh.o
+DRIVERS-$(CONFIG_PPC) += drivers/macintosh/macintosh.o
 DRIVERS-$(CONFIG_MAC) += drivers/macintosh/macintosh.o
 DRIVERS-$(CONFIG_ISAPNP) += drivers/pnp/pnp.o
 DRIVERS-$(CONFIG_SGI_IP22) += drivers/sgi/sgi.a
@@ -185,6 +187,7 @@
 DRIVERS-$(CONFIG_MD) += drivers/md/mddev.o
 DRIVERS-$(CONFIG_BLUEZ) += drivers/bluetooth/bluetooth.o
 DRIVERS-$(CONFIG_HOTPLUG_PCI) += drivers/hotplug/vmlinux-obj.o
+DRIVERS-$(CONFIG_ISDN_BOOL) += drivers/isdn/vmlinux-obj.o
 
 DRIVERS := $(DRIVERS-y)
 
@@ -201,10 +204,15 @@
 	drivers/zorro/devlist.h drivers/zorro/gen-devlist \
 	drivers/sound/bin2hex drivers/sound/hex2hex \
 	drivers/atm/fore200e_mkfirm drivers/atm/{pca,sba}*{.bin,.bin1,.bin2} \
+	drivers/scsi/aic7xxx/aicasm/aicasm \
 	drivers/scsi/aic7xxx/aicasm/aicasm_gram.c \
+	drivers/scsi/aic7xxx/aicasm/aicasm_gram.h \
+	drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.c \
+	drivers/scsi/aic7xxx/aicasm/aicasm_macro_gram.h \
+	drivers/scsi/aic7xxx/aicasm/aicasm_macro_scan.c \
 	drivers/scsi/aic7xxx/aicasm/aicasm_scan.c \
+	drivers/scsi/aic7xxx/aicasm/aicdb.h \
 	drivers/scsi/aic7xxx/aicasm/y.tab.h \
-	drivers/scsi/aic7xxx/aicasm/aicasm \
 	drivers/scsi/53c700_d.h \
 	net/khttpd/make_times_h \
 	net/khttpd/times.h \
@@ -243,6 +251,16 @@
 
 include arch/$(ARCH)/Makefile
 
+# Extra cflags for kbuild 2.4.  The default is to forbid includes by kernel code
+# from user space headers.  Some UML code requires user space headers, in the
+# UML Makefiles add 'kbuild_2_4_nostdinc :=' before include Rules.make.  No
+# other kernel code should include user space headers, if you need
+# 'kbuild_2_4_nostdinc :=' or -I/usr/include for kernel code and you are not UML
+# then your code is broken!  KAO.
+
+kbuild_2_4_nostdinc	:= -nostdinc $(shell $(CC) -print-search-dirs | sed -ne 's/install: \(.*\)/-I \1include/gp')
+export kbuild_2_4_nostdinc
+
 export	CPPFLAGS CFLAGS CFLAGS_KERNEL AFLAGS AFLAGS_KERNEL
 
 export	NETWORKS DRIVERS LIBS HEAD LDFLAGS LINKFLAGS MAKEBOOT ASFLAGS
@@ -258,8 +276,8 @@
 boot: vmlinux
 	@$(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" -C arch/$(ARCH)/boot
 
-vmlinux: include/linux/version.h $(CONFIGURATION) init/main.o init/version.o linuxsubdirs
-	$(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o \
+vmlinux: include/linux/version.h $(CONFIGURATION) init/main.o init/version.o init/do_mounts.o linuxsubdirs
+	$(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o init/do_mounts.o \
 		--start-group \
 		$(CORE_FILES) \
 		$(DRIVERS) \
@@ -338,13 +356,16 @@
 init/main.o: init/main.c include/config/MARKER
 	$(CC) $(CFLAGS) $(CFLAGS_KERNEL) $(PROFILING) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) -c -o $*.o $<
 
+init/do_mounts.o: init/do_mounts.c include/config/MARKER
+	$(CC) $(CFLAGS) $(CFLAGS_KERNEL) $(PROFILING) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) -c -o $*.o $<
+
 fs lib mm ipc kernel drivers net: dummy
 	$(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" $(subst $@, _dir_$@, $@)
 
 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 '*.[ch]' | xargs etags -a
+	{ find include/asm-${ARCH} -name '*.h' -print ; \
+	find include -type d \( -name "asm-*" -o -name config \) -prune -o -name '*.h' -print ; \
+	find $(SUBDIRS) init -name '*.[ch]' ; } | grep -v SCCS | etags -
 
 # Exuberant ctags works better with -I
 tags: dummy
@@ -451,6 +472,11 @@
 
 htmldocs: sgmldocs
 	$(MAKE) -C Documentation/DocBook html
+
+mandocs:
+	chmod 755 $(TOPDIR)/scripts/kernel-doc
+	chmod 755 $(TOPDIR)/scripts/split-man
+	$(MAKE) -C Documentation/DocBook man
 
 sums:
 	find . -type f -print | sort | xargs sum > .SUMS
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/README linux/README
--- linux.orig/README	Fri Oct  5 19:10:00 2001
+++ linux/README	Tue May 28 22:39:23 2002
@@ -150,13 +150,12 @@
 
 COMPILING the kernel:
 
- - Make sure you have gcc-2.91.66 (egcs-1.1.2) available.  gcc 2.95.2 may
+ - Make sure you have gcc 2.95.3 available.  gcc 2.91.66 (egcs-1.1.2) may
    also work but is not as safe, and *gcc 2.7.2.3 is no longer supported*.
    Also remember to upgrade your binutils package (for as/ld/nm and company)
    if necessary. For more information, refer to ./Documentation/Changes.
 
-   Please note that you can still run a.out user programs with this
-   kernel.
+   Please note that you can still run a.out user programs with this kernel.
 
  - Do a "make bzImage" to create a compressed kernel image.  If you want
    to make a boot disk (without root filesystem or LILO), insert a floppy
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/Rules.make linux/Rules.make
--- linux.orig/Rules.make	Mon Feb 25 19:37:52 2002
+++ linux/Rules.make	Tue May 28 22:39:24 2002
@@ -32,6 +32,7 @@
 unexport subdir-
 
 comma	:= ,
+EXTRA_CFLAGS_nostdinc := $(EXTRA_CFLAGS) $(kbuild_2_4_nostdinc)
 
 #
 # Get things started.
@@ -50,15 +51,15 @@
 #
 
 %.s: %.c
-	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -S $< -o $@
+	$(CC) $(CFLAGS) $(EXTRA_CFLAGS_nostdinc) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) $(CFLAGS_$@) -S $< -o $@
 
 %.i: %.c
-	$(CPP) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) $< > $@
+	$(CPP) $(CFLAGS) $(EXTRA_CFLAGS_nostdinc) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) $(CFLAGS_$@) $< > $@
 
 %.o: %.c
-	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) $(CFLAGS_$@) -c -o $@ $<
+	$(CC) $(CFLAGS) $(EXTRA_CFLAGS_nostdinc) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) $(CFLAGS_$@) -c -o $@ $<
 	@ ( \
-	    echo 'ifeq ($(strip $(subst $(comma),:,$(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@))),$$(strip $$(subst $$(comma),:,$$(CFLAGS) $$(EXTRA_CFLAGS) $$(CFLAGS_$@))))' ; \
+	    echo 'ifeq ($(strip $(subst $(comma),:,$(CFLAGS) $(EXTRA_CFLAGS_nostdinc) $(CFLAGS_$@))),$$(strip $$(subst $$(comma),:,$$(CFLAGS) $$(EXTRA_CFLAGS_nostdinc) $$(CFLAGS_$@))))' ; \
 	    echo 'FILES_FLAGS_UP_TO_DATE += $@' ; \
 	    echo 'endif' \
 	) > $(dir $@)/.$(notdir $@).flags
@@ -81,7 +82,7 @@
 endif
 
 %.lst: %.c
-	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -g -c -o $*.o $<
+	$(CC) $(CFLAGS) $(EXTRA_CFLAGS_nostdinc) $(CFLAGS_$@) -g -c -o $*.o $<
 	$(TOPDIR)/scripts/makelst $* $(TOPDIR) $(OBJDUMP)
 #
 #
@@ -125,7 +126,7 @@
 # This make dependencies quickly
 #
 fastdep: dummy
-	$(TOPDIR)/scripts/mkdep $(CFLAGS) $(EXTRA_CFLAGS) -- $(wildcard *.[chS]) > .depend
+	$(TOPDIR)/scripts/mkdep $(CFLAGS) $(EXTRA_CFLAGS_nostdinc) -- $(wildcard *.[chS]) > .depend
 ifdef ALL_SUB_DIRS
 	$(MAKE) $(patsubst %,_sfdep_%,$(ALL_SUB_DIRS)) _FASTDEP_ALL_SUB_DIRS="$(ALL_SUB_DIRS)"
 endif
@@ -175,7 +176,7 @@
 _modinst__: dummy
 ifneq "$(strip $(ALL_MOBJS))" ""
 	mkdir -p $(MODLIB)/kernel/$(MOD_DESTDIR)
-	cp $(ALL_MOBJS) $(MODLIB)/kernel/$(MOD_DESTDIR)$(MOD_TARGET)
+	cp $(ALL_MOBJS) $(MODLIB)/kernel/$(MOD_DESTDIR)
 endif
 
 .PHONY: modules_install
@@ -224,9 +225,9 @@
 
 $(MODINCL)/%.ver: %.c
 	@if [ ! -r $(MODINCL)/$*.stamp -o $(MODINCL)/$*.stamp -ot $< ]; then \
-		echo '$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -E -D__GENKSYMS__ $<'; \
+		echo '$(CC) $(CFLAGS) $(EXTRA_CFLAGS_nostdinc) -E -D__GENKSYMS__ $<'; \
 		echo '| $(GENKSYMS) $(genksyms_smp_prefix) -k $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) > $@.tmp'; \
-		$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -E -D__GENKSYMS__ $< \
+		$(CC) $(CFLAGS) $(EXTRA_CFLAGS_nostdinc) -E -D__GENKSYMS__ $< \
 		| $(GENKSYMS) $(genksyms_smp_prefix) -k $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) > $@.tmp; \
 		if [ -r $@ ] && cmp -s $@ $@.tmp; then echo $@ is unchanged; rm -f $@.tmp; \
 		else echo mv $@.tmp $@; mv -f $@.tmp $@; fi; \
@@ -272,9 +273,9 @@
 
 ifneq "$(strip $(export-objs))" ""
 $(export-objs): $(export-objs:.o=.c) $(TOPDIR)/include/linux/modversions.h
-	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) $(CFLAGS_$@) -DEXPORT_SYMTAB -c $(@:.o=.c)
+	$(CC) $(CFLAGS) $(EXTRA_CFLAGS_nostdinc) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) $(CFLAGS_$@) -DEXPORT_SYMTAB -c $(@:.o=.c)
 	@ ( \
-	    echo 'ifeq ($(strip $(subst $(comma),:,$(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -DEXPORT_SYMTAB)),$$(strip $$(subst $$(comma),:,$$(CFLAGS) $$(EXTRA_CFLAGS) $$(CFLAGS_$@) -DEXPORT_SYMTAB)))' ; \
+	    echo 'ifeq ($(strip $(subst $(comma),:,$(CFLAGS) $(EXTRA_CFLAGS_nostdinc) $(CFLAGS_$@) -DEXPORT_SYMTAB)),$$(strip $$(subst $$(comma),:,$$(CFLAGS) $$(EXTRA_CFLAGS_nostdinc) $$(CFLAGS_$@) -DEXPORT_SYMTAB)))' ; \
 	    echo 'FILES_FLAGS_UP_TO_DATE += $@' ; \
 	    echo 'endif' \
 	) > $(dir $@)/.$(notdir $@).flags
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/alpha/Makefile linux/arch/alpha/Makefile
--- linux.orig/arch/alpha/Makefile	Mon Dec  4 01:45:20 2000
+++ linux/arch/alpha/Makefile	Tue May 28 22:39:15 2002
@@ -40,20 +40,20 @@
     CFLAGS := $(CFLAGS) -mcpu=pca56
     mcpu_done := y
   endif
-  ifeq ($(mcpu_done)$(CONFIG_ALPHA_PYXIS),ny)
-    CFLAGS := $(CFLAGS) -mcpu=ev56
-    mcpu_done := y
-  endif
-  ifeq ($(mcpu_done)$(CONFIG_ALPHA_POLARIS),ny)
-    ifeq ($(have_mcpu_pca56),y)
-      CFLAGS := $(CFLAGS) -mcpu=pca56
-    else
-      CFLAGS := $(CFLAGS) -mcpu=ev56
-    endif
+  ifeq ($(mcpu_done)$(CONFIG_ALPHA_POLARIS)$(have_mcpu_pca56),nyy)
+    CFLAGS := $(CFLAGS) -mcpu=pca56
     mcpu_done := y
   endif
   ifeq ($(mcpu_done)$(CONFIG_ALPHA_EV4),ny)
     CFLAGS := $(CFLAGS) -mcpu=ev4
+    mcpu_done := y
+  endif
+  ifeq ($(mcpu_done)$(CONFIG_ALPHA_EV56),ny)
+    CFLAGS := $(CFLAGS) -mcpu=ev56
+    mcpu_done := y
+  endif
+  ifeq ($(mcpu_done)$(CONFIG_ALPHA_EV5),ny)
+    CFLAGS := $(CFLAGS) -mcpu=ev5
     mcpu_done := y
   endif
   ifeq ($(mcpu_done)$(CONFIG_ALPHA_EV67)$(have_mcpu_ev67),nyy)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/alpha/config.in linux/arch/alpha/config.in
--- linux.orig/arch/alpha/config.in	Tue Nov 20 23:49:31 2001
+++ linux/arch/alpha/config.in	Tue May 28 22:39:19 2002
@@ -102,19 +102,44 @@
 then
 	define_bool CONFIG_ALPHA_EB64P y
 fi
-if [ "$CONFIG_ALPHA_EB164" = "y" -o "$CONFIG_ALPHA_PC164" = "y" \
-	-o "$CONFIG_ALPHA_ALCOR" = "y" -o "$CONFIG_ALPHA_TAKARA" = "y" ]
+if [ "$CONFIG_ALPHA_ALCOR" = "y" ]
 then
 	define_bool CONFIG_ALPHA_EV5 y
 	define_bool CONFIG_ALPHA_CIA y
+	bool 'EV56 CPU (speed >= 366MHz)?' CONFIG_ALPHA_EV56
 fi
-if [ "$CONFIG_ALPHA_MIKASA" = "y" -o "$CONFIG_ALPHA_NORITAKE" = "y" ]
+if [ "$CONFIG_ALPHA_EB164" = "y" ]
+then
+	define_bool CONFIG_ALPHA_EV5 y
+	define_bool CONFIG_ALPHA_CIA y
+fi
+if [ "$CONFIG_ALPHA_PC164" = "y" -o "$CONFIG_ALPHA_TAKARA" = "y" ]
+then
+	define_bool CONFIG_ALPHA_EV5 y
+	define_bool CONFIG_ALPHA_EV56 y
+	define_bool CONFIG_ALPHA_CIA y
+fi
+if [ "$CONFIG_ALPHA_MIKASA" = "y" ]
 then
 	bool 'EV5 CPU daughtercard (model 5/xxx)?' CONFIG_ALPHA_PRIMO
 	if [ "$CONFIG_ALPHA_PRIMO" = "y" ]
 	then
 		define_bool CONFIG_ALPHA_EV5 y
 		define_bool CONFIG_ALPHA_CIA y
+		bool 'EV56 CPU (speed >= 333MHz)?' CONFIG_ALPHA_EV56
+	else
+		define_bool CONFIG_ALPHA_EV4 y
+		define_bool CONFIG_ALPHA_APECS y
+	fi
+fi
+if [ "$CONFIG_ALPHA_NORITAKE" = "y" ]
+then
+	bool 'EV5 CPU (model 5/xxx)?' CONFIG_ALPHA_PRIMO
+	if [ "$CONFIG_ALPHA_PRIMO" = "y" ]
+	then
+		define_bool CONFIG_ALPHA_EV5 y
+		define_bool CONFIG_ALPHA_CIA y
+		bool 'EV56 CPU (speed >= 333MHz)?' CONFIG_ALPHA_EV56
 	else
 		define_bool CONFIG_ALPHA_EV4 y
 		define_bool CONFIG_ALPHA_APECS y
@@ -135,6 +160,7 @@
 	-o "$CONFIG_ALPHA_SX164" = "y" -o "$CONFIG_ALPHA_RUFFIAN" = "y" ]
 then
 	define_bool CONFIG_ALPHA_EV5 y
+	define_bool CONFIG_ALPHA_EV56 y
 	define_bool CONFIG_ALPHA_CIA y
 	define_bool CONFIG_ALPHA_PYXIS y
 fi
@@ -159,10 +185,12 @@
 then
 	define_bool CONFIG_ALPHA_EV5 y
 	define_bool CONFIG_ALPHA_MCPCIA y
+	bool 'EV56 CPU (speed >= 400MHz)?' CONFIG_ALPHA_EV56
 fi
 if [ "$CONFIG_ALPHA_RX164" = "y" ]
 then
 	define_bool CONFIG_ALPHA_EV5 y
+	define_bool CONFIG_ALPHA_EV56 y
 	define_bool CONFIG_ALPHA_POLARIS y
 fi
 if [ "$CONFIG_ALPHA_JENSEN" = "y" ]
@@ -250,7 +278,7 @@
 	"ELF		CONFIG_KCORE_ELF	\
 	 A.OUT		CONFIG_KCORE_AOUT" ELF
 fi
-if [ "$CONFIG_PROC_FS" != "n" -a "$CONFIG_ALPHA_SRM" = "y" ]; then
+if [ "$CONFIG_PROC_FS" != "n" ]; then
    tristate 'SRM environment through procfs' CONFIG_SRM_ENV
 fi
  
@@ -371,9 +399,7 @@
 source drivers/usb/Config.in
 source drivers/input/Config.in
 
-if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-   source net/bluetooth/Config.in
-fi
+source net/bluetooth/Config.in
 
 mainmenu_option next_comment
 comment 'Kernel hacking'
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/alpha/kernel/alpha_ksyms.c linux/arch/alpha/kernel/alpha_ksyms.c
--- linux.orig/arch/alpha/kernel/alpha_ksyms.c	Mon Feb 25 19:37:52 2002
+++ linux/arch/alpha/kernel/alpha_ksyms.c	Tue May 28 22:39:15 2002
@@ -58,11 +58,12 @@
 EXPORT_SYMBOL(probe_irq_mask);
 EXPORT_SYMBOL(screen_info);
 EXPORT_SYMBOL(perf_irq);
-#ifdef CONFIG_ALPHA_SRM
 EXPORT_SYMBOL(callback_getenv);
 EXPORT_SYMBOL(callback_setenv);
 EXPORT_SYMBOL(callback_save_env);
-#endif /* CONFIG_ALPHA_SRM */
+#ifdef CONFIG_ALPHA_GENERIC
+EXPORT_SYMBOL(alpha_using_srm);
+#endif /* CNFIG_ALPHA_GENERIC */
 
 /* platform dependent support */
 EXPORT_SYMBOL(_inb);
@@ -214,6 +215,7 @@
 EXPORT_SYMBOL(smp_imb);
 EXPORT_SYMBOL(cpu_data);
 EXPORT_SYMBOL(__cpu_number_map);
+EXPORT_SYMBOL(__cpu_logical_map);
 EXPORT_SYMBOL(smp_num_cpus);
 EXPORT_SYMBOL(smp_call_function);
 EXPORT_SYMBOL(smp_call_function_on_cpu);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/alpha/kernel/entry.S linux/arch/alpha/kernel/entry.S
--- linux.orig/arch/alpha/kernel/entry.S	Fri Nov  9 21:45:35 2001
+++ linux/arch/alpha/kernel/entry.S	Tue May 28 22:39:12 2002
@@ -10,7 +10,7 @@
 
 #define SIGCHLD 20
 
-#define NR_SYSCALLS 378
+#define NR_SYSCALLS 382
 
 /*
  * These offsets must match with alpha_mv in <asm/machvec.h>.
@@ -1148,3 +1148,9 @@
 	.quad sys_gettid
 	.quad sys_readahead
 	.quad sys_ni_syscall			/* 380, sys_security */
+	.quad sys_tkill
+
+/* Remember to update everything, kids.  */
+.ifne (. - sys_call_table) - (NR_SYSCALLS * 8)
+.err
+.endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/alpha/kernel/pci_iommu.c linux/arch/alpha/kernel/pci_iommu.c
--- linux.orig/arch/alpha/kernel/pci_iommu.c	Mon Feb 25 19:37:52 2002
+++ linux/arch/alpha/kernel/pci_iommu.c	Tue May 28 22:39:31 2002
@@ -217,9 +217,14 @@
 	}
 
 	/* If the machine doesn't define a pci_tbi routine, we have to
-	   assume it doesn't support sg mapping.  */
+	   assume it doesn't support sg mapping, and, since we tried to
+	   use direct_map above, it now must be considered an error. */
 	if (! alpha_mv.mv_pci_tbi) {
-		printk(KERN_WARNING "pci_map_single failed: no hw sg\n");
+		static int been_here = 0; /* Only print the message once. */
+		if (!been_here) {
+		    printk(KERN_WARNING "pci_map_single: no HW sg\n");
+		    been_here = 1;
+		}
 		return 0;
 	}
 		
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/alpha/kernel/setup.c linux/arch/alpha/kernel/setup.c
--- linux.orig/arch/alpha/kernel/setup.c	Sat Nov 17 02:38:39 2001
+++ linux/arch/alpha/kernel/setup.c	Tue May 28 22:39:18 2002
@@ -440,12 +440,6 @@
         return MKDEV(TTY_MAJOR, 64 + c->index);
 }
 
-static int srm_console_wait_key(struct console *co)
-{
-  /* Huh? */
-	return 1;
-}
-
 static int __init srm_console_setup(struct console *co, char *options)
 {
 	return 1;
@@ -455,7 +449,6 @@
 	name:		"srm0",
 	write:		srm_console_write,
 	device:		srm_console_device,
-	wait_key:	srm_console_wait_key,
 	setup:		srm_console_setup,
 	flags:		CON_PRINTBUFFER | CON_ENABLED, /* fake it out */
 	index:		-1,
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/alpha/kernel/signal.c linux/arch/alpha/kernel/signal.c
--- linux.orig/arch/alpha/kernel/signal.c	Fri Nov  9 21:45:35 2001
+++ linux/arch/alpha/kernel/signal.c	Tue May 28 22:39:27 2002
@@ -717,9 +717,7 @@
 
 			default:
 				lock_kernel();
-				sigaddset(&current->pending.signal, signr);
-				current->flags |= PF_SIGNALED;
-				do_exit(exit_code);
+				sig_exit(signr, exit_code, &info);
 				/* NOTREACHED */
 			}
 			continue;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/alpha/kernel/smp.c linux/arch/alpha/kernel/smp.c
--- linux.orig/arch/alpha/kernel/smp.c	Fri Dec 21 17:41:53 2001
+++ linux/arch/alpha/kernel/smp.c	Tue May 28 22:39:21 2002
@@ -184,9 +184,23 @@
 	 */
 	wait_boot_cpu_to_stop(cpuid);
 	mb();
+ try_again:
 	calibrate_delay();
 
 	smp_store_cpu_info(cpuid);
+
+	{
+#define LPJ(c) ((long)cpu_data[c].loops_per_jiffy)
+	  static int tries = 3;
+	  long diff = LPJ(boot_cpuid) - LPJ(cpuid);
+	  if (diff < 0) diff = -diff;
+				
+	  if (diff > LPJ(boot_cpuid)/10 && --tries) {
+	    printk("Bogus BogoMIPS for cpu %d - retrying...\n", cpuid);
+	    goto try_again;
+	  }
+	}
+
 	/*
 	 * Allow master to continue only after we written
 	 * the loops_per_jiffy.
@@ -1065,7 +1079,8 @@
 }
 
 void
-flush_icache_page(struct vm_area_struct *vma, struct page *page)
+flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
+			unsigned long addr, int len)
 {
 	struct mm_struct *mm = vma->vm_mm;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/alpha/kernel/srm_env.c linux/arch/alpha/kernel/srm_env.c
--- linux.orig/arch/alpha/kernel/srm_env.c	Sun Oct 21 17:20:57 2001
+++ linux/arch/alpha/kernel/srm_env.c	Tue May 28 22:39:17 2002
@@ -1,27 +1,20 @@
 /*
- * srm_env.c - Access to SRC environment variables through
- *             the linux procfs
+ * srm_env.c - Access to SRM environment
+ *             variables through linux' procfs
  *
- * (C)2001, Jan-Benedict Glaw <jbglaw@lug-owl.de>
+ * Copyright (C) 2001-2002 Jan-Benedict Glaw <jbglaw@lug-owl.de>
  *
  * This driver is at all a modified version of Erik Mouw's
- * ./linux/Documentation/DocBook/procfs_example.c, so: thanky
+ * ./linux/Documentation/DocBook/procfs_example.c, so: thank
  * you, Erik! He can be reached via email at
  * <J.A.K.Mouw@its.tudelft.nl>. It is based on an idea
- * provided by DEC^WCompaq's "Jumpstart" CD. They included
- * a patch like this as well. Thanks for idea!
- *
- *
- * This software has been developed while working on the LART
- * computing board (http://www.lart.tudelft.nl/). The
- * development has been sponsored by the Mobile Multi-media
- * Communications (http://www.mmc.tudelft.nl/) and Ubiquitous
- * Communications (http://www.ubicom.tudelft.nl/) projects.
+ * provided by DEC^WCompaq^WIntel's "Jumpstart" CD. They
+ * included a patch like this as well. Thanks for idea!
  *
  * This program is free software; you can redistribute
  * it and/or modify it under the terms of the GNU General
- * Public License as published by the Free Software
- * Foundation version 2.
+ * Public License version 2 as published by the Free Software
+ * Foundation.
  *
  * This program is distributed in the hope that it will be
  * useful, but WITHOUT ANY WARRANTY; without even the implied
@@ -36,6 +29,24 @@
  *
  */
 
+/*
+ * Changelog
+ * ~~~~~~~~~
+ *
+ * Wed, 22 May 2002 00:11:21 +0200
+ * 	- Fix typo on comment (SRC -> SRM)
+ * 	- Call this "Version 0.0.4"
+ *
+ * Tue,  9 Apr 2002 18:44:40 +0200
+ * 	- Implement access by variable name and additionally
+ * 	  by number. This is done by creating two subdirectories
+ * 	  where one holds all names (like the old directory
+ * 	  did) and the other holding 256 files named like "0",
+ * 	  "1" and so on.
+ * 	- Call this "Version 0.0.3"
+ *
+ */
+
 #include <linux/kernel.h>
 #include <linux/config.h>
 #include <linux/module.h>
@@ -43,11 +54,13 @@
 #include <linux/proc_fs.h>
 #include <asm/console.h>
 #include <asm/uaccess.h>
+#include <asm/machvec.h>
 
-#define DIRNAME		"srm_environment"	/* Subdir in /proc/	*/
-#define VERSION		"0.0.2"			/* Module version	*/
-#define NAME		"srm_env"		/* Module name		*/
-#define DEBUG
+#define BASE_DIR	"srm_environment"	/* Subdir in /proc/		*/
+#define NAMED_DIR	"named_variables"	/* Subdir for known variables	*/
+#define NUMBERED_DIR	"numbered_variables"	/* Subdir for all variables	*/
+#define VERSION		"0.0.4"			/* Module version		*/
+#define NAME		"srm_env"		/* Module name			*/
 
 MODULE_AUTHOR("Jan-Benedict Glaw <jbglaw@lug-owl.de>");
 MODULE_DESCRIPTION("Accessing Alpha SRM environment through procfs interface");
@@ -60,8 +73,12 @@
 	struct proc_dir_entry	*proc_entry;
 } srm_env_t;
 
-static struct proc_dir_entry	*directory;
-static srm_env_t	srm_entries[] = {
+static struct proc_dir_entry	*base_dir;
+static struct proc_dir_entry	*named_dir;
+static struct proc_dir_entry	*numbered_dir;
+static char			number[256][4];
+
+static srm_env_t	srm_named_entries[] = {
 	{ "auto_action",	ENV_AUTO_ACTION		},
 	{ "boot_dev",		ENV_BOOT_DEV		},
 	{ "bootdef_dev",	ENV_BOOTDEF_DEV		},
@@ -79,10 +96,11 @@
 	{ "tty_dev",		ENV_TTY_DEV		},
 	{ NULL,			0			},
 };
+static srm_env_t	srm_numbered_entries[256];
 
-static int srm_env_read(char *page, char **start, off_t off, int count,
-		int *eof, void *data)
-{
+static int
+srm_env_read(char *page, char **start, off_t off, int count, int *eof,
+		void *data) {
 	int		nbytes;
 	unsigned long	ret;
 	srm_env_t	*entry;
@@ -107,10 +125,9 @@
 	return nbytes;
 }
 
-
-static int srm_env_write(struct file *file, const char *buffer,
-		unsigned long count, void *data)
-{
+static int
+srm_env_write(struct file *file, const char *buffer, unsigned long count,
+		void *data) {
 #define BUFLEN	512
 	int		nbytes;
 	srm_env_t	*entry;
@@ -126,8 +143,8 @@
 		MOD_DEC_USE_COUNT;
 		return -ENOMEM;
 	}
-		
-	//memcpy(aligned_buffer, buffer, nbytes)
+
+	/* memcpy(aligned_buffer, buffer, nbytes) */
 
 	if(copy_from_user(buf, buffer, count)) {
 		MOD_DEC_USE_COUNT;
@@ -149,55 +166,142 @@
 	return nbytes;
 }
 
-static void srm_env_cleanup(void)
-{
+static void
+srm_env_cleanup(void) {
 	srm_env_t	*entry;
+	unsigned long	var_num;
 
-	if(directory) {
-		entry = srm_entries;
-		while(entry->name != NULL && entry->id != 0) {
-			if(entry->proc_entry) {
-				remove_proc_entry(entry->name, directory);
-				entry->proc_entry = NULL;
+	if(base_dir) {
+		/*
+		 * Remove named entries
+		 */
+		if(named_dir) {
+			entry = srm_named_entries;
+			while(entry->name != NULL && entry->id != 0) {
+				if(entry->proc_entry) {
+					remove_proc_entry(entry->name,
+							named_dir);
+					entry->proc_entry = NULL;
+				}
+				entry++;
 			}
-			entry++;
+			remove_proc_entry(NAMED_DIR, base_dir);
 		}
-		remove_proc_entry(DIRNAME, NULL);
+
+		/*
+		 * Remove numbered entries
+		 */
+		if(numbered_dir) {
+			for(var_num = 0; var_num <= 255; var_num++) {
+				entry =	&srm_numbered_entries[var_num];
+
+				if(entry->proc_entry) {
+					remove_proc_entry(entry->name,
+							numbered_dir);
+					entry->proc_entry	= NULL;
+					entry->name		= NULL;
+				}
+			}
+			remove_proc_entry(NUMBERED_DIR, base_dir);
+		}
+
+		remove_proc_entry(BASE_DIR, NULL);
 	}
 
 	return;
 }
 
-static int __init srm_env_init(void)
-{
+static int __init
+srm_env_init(void) {
 	srm_env_t	*entry;
-	
+	unsigned long	var_num;
+
+	/*
+	 * Check system
+	 */
 	if(!alpha_using_srm) {
 		printk(KERN_INFO "%s: This Alpha system doesn't "
 				"know about SRM...\n", __FUNCTION__);
 		return -ENODEV;
 	}
 
-	directory = proc_mkdir(DIRNAME, NULL);
-	if(directory == NULL)
-		return -ENOMEM;
-	
-	directory->owner = THIS_MODULE;
-	
-	/* Now create all the nodes... */
-	entry = srm_entries;
+	/*
+	 * Init numbers
+	 */
+	for(var_num = 0; var_num <= 255; var_num++)
+		sprintf(number[var_num], "%ld", var_num);
+
+	/*
+	 * Create base directory
+	 */
+	base_dir = proc_mkdir(BASE_DIR, NULL);
+	if(base_dir == NULL) {
+		printk(KERN_ERR "Couldn't create base dir /proc/%s\n",
+				BASE_DIR);
+		goto cleanup;
+	}
+	base_dir->owner = THIS_MODULE;
+
+	/*
+	 * Create per-name subdirectory
+	 */
+	named_dir = proc_mkdir(NAMED_DIR, base_dir);
+	if(named_dir == NULL) {
+		printk(KERN_ERR "Couldn't create dir /proc/%s/%s\n",
+				BASE_DIR, NAMED_DIR);
+		goto cleanup;
+	}
+	named_dir->owner = THIS_MODULE;
+
+	/*
+	 * Create per-number subdirectory
+	 */
+	numbered_dir = proc_mkdir(NUMBERED_DIR, base_dir);
+	if(numbered_dir == NULL) {
+		printk(KERN_ERR "Couldn't create dir /proc/%s/%s\n",
+				BASE_DIR, NUMBERED_DIR);
+		goto cleanup;
+
+	}
+	numbered_dir->owner = THIS_MODULE;
+
+	/*
+	 * Create all named nodes
+	 */
+	entry = srm_named_entries;
 	while(entry->name != NULL && entry->id != 0) {
-		entry->proc_entry = create_proc_entry(entry->name, 0644,
-				directory);
+		entry->proc_entry = create_proc_entry(entry->name,
+				0644, named_dir);
 		if(entry->proc_entry == NULL)
 			goto cleanup;
-		entry->proc_entry->data		= entry;
+
+		entry->proc_entry->data		= (void *)entry;
+		entry->proc_entry->owner	= THIS_MODULE;
 		entry->proc_entry->read_proc	= srm_env_read;
 		entry->proc_entry->write_proc	= srm_env_write;
-		entry->proc_entry->owner	= THIS_MODULE;
+
 		entry++;
 	}
-	
+
+	/*
+	 * Create all numbered nodes
+	 */
+	for(var_num = 0; var_num <= 255; var_num++) {
+		entry = &srm_numbered_entries[var_num];
+		entry->name = number[var_num];
+
+		entry->proc_entry = create_proc_entry(entry->name,
+				0644, numbered_dir);
+		if(entry->proc_entry == NULL)
+			goto cleanup;
+
+		entry->id			= var_num;
+		entry->proc_entry->data		= (void *)entry;
+		entry->proc_entry->owner	= THIS_MODULE;
+		entry->proc_entry->read_proc	= srm_env_read;
+		entry->proc_entry->write_proc	= srm_env_write;
+	}
+
 	printk(KERN_INFO "%s: version %s loaded successfully\n", NAME,
 			VERSION);
 	return 0;
@@ -207,9 +311,8 @@
 	return -ENOMEM;
 }
 
-
-static void __exit srm_env_exit(void)
-{
+static void __exit
+srm_env_exit(void) {
 	srm_env_cleanup();
 	printk(KERN_INFO "%s: unloaded successfully\n", NAME);
 	return;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/alpha/math-emu/math.c linux/arch/alpha/math-emu/math.c
--- linux.orig/arch/alpha/math-emu/math.c	Fri Sep 22 20:54:09 2000
+++ linux/arch/alpha/math-emu/math.c	Tue May 28 22:39:31 2002
@@ -220,12 +220,12 @@
 				FP_CONV(S,D,1,1,SR,DB);
 				goto pack_s;
 			} else {
-				/* CVTST need do nothing else but copy the
-				   bits and repack.  */
+				vb = alpha_read_fp_reg_s(fb);
+				FP_UNPACK_SP(SB, &vb);
 				DR_c = DB_c;
 				DR_s = DB_s;
 				DR_e = DB_e;
-				DR_f = DB_f;
+				DR_f = SB_f << (52 - 23);
 				goto pack_d;
 			}
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/alpha/mm/init.c linux/arch/alpha/mm/init.c
--- linux.orig/arch/alpha/mm/init.c	Fri Sep 21 03:02:03 2001
+++ linux/arch/alpha/mm/init.c	Tue May 28 22:39:23 2002
@@ -380,7 +380,7 @@
 		free_page(addr);
 		totalram_pages++;
 	}
-	printk ("Freeing unused kernel memory: %ldk freed\n",
+	printk (KERN_INFO "Freeing unused kernel memory: %ldk freed\n",
 		(&__init_end - &__init_begin) >> 10);
 }
 
@@ -395,7 +395,7 @@
 		free_page(start);
 		totalram_pages++;
 	}
-	printk ("Freeing initrd memory: %ldk freed\n", (end - __start) >> 10);
+	printk (KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - __start) >> 10);
 }
 #endif
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/alpha/mm/numa.c linux/arch/alpha/mm/numa.c
--- linux.orig/arch/alpha/mm/numa.c	Sun Aug 12 17:38:48 2001
+++ linux/arch/alpha/mm/numa.c	Tue May 28 22:39:14 2002
@@ -312,7 +312,7 @@
 		printk(".");				\
 } while(0)
 
-#define clobber(p, size) memset((p)->virtual, 0xaa, (size))
+#define clobber(p, size) memset(page_address(p), 0xaa, (size))
 
 void __init mem_stress(void)
 {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/Makefile linux/arch/arm/Makefile
--- linux.orig/arch/arm/Makefile	Fri Nov  9 21:58:02 2001
+++ linux/arch/arm/Makefile	Tue May 28 22:39:24 2002
@@ -11,10 +11,6 @@
 GZFLAGS		:=-9
 CFLAGS		+=-fno-common -pipe
 
-ifneq ($(CONFIG_NO_FRAME_POINTER),y)
-CFLAGS		:=$(CFLAGS:-fomit-frame-pointer=)
-endif
-
 ifeq ($(CONFIG_DEBUG_INFO),y)
 CFLAGS		+=-g
 endif
@@ -39,10 +35,12 @@
 tune-$(CONFIG_CPU_ARM710)	:=-mtune=arm710
 tune-$(CONFIG_CPU_ARM720T)	:=-mtune=arm7tdmi
 tune-$(CONFIG_CPU_ARM920T)	:=-mtune=arm9tdmi
+tune-$(CONFIG_CPU_ARM922T)	:=-mtune=arm9tdmi
 tune-$(CONFIG_CPU_ARM926T)	:=-mtune=arm9tdmi
 tune-$(CONFIG_CPU_SA110)	:=-mtune=strongarm110
 tune-$(CONFIG_CPU_SA1100)	:=-mtune=strongarm1100
 
+CFLAGS_BOOT	:=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float
 CFLAGS		+=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float
 AFLAGS		+=$(apcs-y) $(arch-y) -mno-fpu -msoft-float
 
@@ -74,6 +72,8 @@
 
 ifeq ($(CONFIG_ARCH_EBSA110),y)
 MACHINE		 = ebsa110
+CFLAGS_3c589_cs	:=-DISA_SIXTEEN_BIT_PERIPHERAL
+export CFLAGS_3c589_cs
 endif
 
 ifeq ($(CONFIG_ARCH_CLPS7500),y)
@@ -121,6 +121,10 @@
 MACHINE		 = integrator
 endif
 
+ifeq ($(CONFIG_ARCH_MX1ADS),y)
+MACHINE		 = mx1ads
+endif
+
 ifeq ($(CONFIG_ARCH_CAMELOT),y)
 MACHINE          = epxa10db
 endif
@@ -130,11 +134,15 @@
 MACHINE		 = clps711x
 endif
 
+ifeq ($(CONFIG_ARCH_FORTUNET),y)
+TEXTADDR	 = 0xc0008000
+endif
+
 ifeq ($(CONFIG_ARCH_ANAKIN),y)
 MACHINE		 = anakin
 endif
 
-export	MACHINE PROCESSOR TEXTADDR GZFLAGS
+export	MACHINE PROCESSOR TEXTADDR GZFLAGS CFLAGS_BOOT
 
 # Only set INCDIR if its not already defined above
 # Grr, ?= doesn't work as all the other assignment operators do.  Make bug?
@@ -207,6 +215,7 @@
 	arch/arm/vmlinux.lds
 
 MRPROPER_FILES	+= \
+	arch/arm/tools/constants.h* \
 	include/asm-arm/arch \
 	include/asm-arm/proc \
 	include/asm-arm/constants.h* \
@@ -254,7 +263,7 @@
 	@( \
 	CFG=$(@:_config=); \
 	if [ -f arch/arm/def-configs/$$CFG ]; then \
-	  [ -f .config ] && $(MV) .config .config.old; \
+	  [ -f .config ] && mv -f .config .config.old; \
 	  cp arch/arm/def-configs/$$CFG .config; \
 	  echo "*** Default configuration for $$CFG installed"; \
 	  echo "*** Next, you may run 'make oldconfig'"; \
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/boot/Makefile linux/arch/arm/boot/Makefile
--- linux.orig/arch/arm/boot/Makefile	Thu Oct 11 16:04:57 2001
+++ linux/arch/arm/boot/Makefile	Tue May 28 22:39:16 2002
@@ -54,6 +54,14 @@
 INITRD_VIRT	 = 0xc0800000
 endif
 
+ifeq ($(CONFIG_ARCH_MX1ADS),y)
+ZTEXTADDR	 = 0x08008000
+endif
+
+ifeq ($(CONFIG_ARCH_CAMELOT),y)
+ZTEXTADDR	 = 0x00008000
+endif
+
 ifeq ($(CONFIG_ARCH_NEXUSPCI),y)
 ZTEXTADDR	 = 0x40008000
 endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/boot/compressed/Makefile linux/arch/arm/boot/compressed/Makefile
--- linux.orig/arch/arm/boot/compressed/Makefile	Thu Oct 11 16:04:57 2001
+++ linux/arch/arm/boot/compressed/Makefile	Tue May 28 22:39:17 2002
@@ -9,7 +9,7 @@
 
 HEAD		 = head.o
 OBJS		 = misc.o
-CFLAGS		 = $(CPPFLAGS) -O2 -DSTDC_HEADERS $(CFLAGS_PROC) -msoft-float
+CFLAGS		 = $(CPPFLAGS) -O2 -DSTDC_HEADERS $(CFLAGS_BOOT)
 FONTC		 = $(TOPDIR)/drivers/video/font_acorn_8x8.c
 ZLDFLAGS	 = -p -X -T vmlinux.lds
 
@@ -33,6 +33,14 @@
 OBJS		+= head-integrator.o
 endif
 
+ifeq ($(CONFIG_ARCH_MX1ADS),y)
+OBJS		+= head-mx1ads.o
+endif
+
+ifeq ($(CONFIG_ARCH_CAMELOT),y)
+OBJS		+= head-epxa10db.o
+endif
+
 ifeq ($(CONFIG_ARCH_FTVPCI),y)
 OBJS		+= head-ftvpci.o
 endif
@@ -84,12 +92,12 @@
 font.o:		$(FONTC)
 		$(CC) $(CFLAGS) -Dstatic= -c -o $@ $(FONTC)
 
-vmlinux.lds:	vmlinux.lds.in
+vmlinux.lds:	vmlinux.lds.in Makefile $(TOPDIR)/arch/$(ARCH)/boot/Makefile $(TOPDIR)/.config
 		@sed "$(SEDFLAGS)" < vmlinux.lds.in > $@
 
 clean:;		rm -f vmlinux core piggy* vmlinux.lds
 
-.PHONY:	vmlinux.lds clean
+.PHONY:	clean
 
 misc.o: misc.c $(TOPDIR)/include/asm/arch/uncompress.h $(TOPDIR)/lib/inflate.c
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/boot/compressed/head-epxa10db.S linux/arch/arm/boot/compressed/head-epxa10db.S
--- linux.orig/arch/arm/boot/compressed/head-epxa10db.S	Thu Jan  1 00:00:00 1970
+++ linux/arch/arm/boot/compressed/head-epxa10db.S	Tue May 28 22:39:13 2002
@@ -0,0 +1,5 @@
+#include <asm/mach-types.h>
+#include <asm/arch/excalibur.h>
+
+		.section	".start", #alloc, #execinstr
+		mov	r7, #MACH_TYPE_CAMELOT
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/boot/compressed/head-mx1ads.S linux/arch/arm/boot/compressed/head-mx1ads.S
--- linux.orig/arch/arm/boot/compressed/head-mx1ads.S	Thu Jan  1 00:00:00 1970
+++ linux/arch/arm/boot/compressed/head-mx1ads.S	Tue May 28 22:39:31 2002
@@ -0,0 +1,4 @@
+#include <asm/mach-types.h>
+
+		.section	".start", #alloc, #execinstr
+		mov	r7, #MACH_TYPE_MX1ADS
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/boot/compressed/head-shark.S linux/arch/arm/boot/compressed/head-shark.S
--- linux.orig/arch/arm/boot/compressed/head-shark.S	Thu Apr 12 19:03:50 2001
+++ linux/arch/arm/boot/compressed/head-shark.S	Tue May 28 22:39:21 2002
@@ -1,5 +1,5 @@
 /* The head-file for the Shark
- * by Alexander Schulz <aschulz@netwinder.org>
+ * by Alexander Schulz
  *
  * Does the following:
  * - get the memory layout from firmware. This can only be done as long as the mmu
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/boot/compressed/head.S linux/arch/arm/boot/compressed/head.S
--- linux.orig/arch/arm/boot/compressed/head.S	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/boot/compressed/head.S	Tue May 28 22:39:30 2002
@@ -18,14 +18,14 @@
  * Please select one of the following when turning on debugging.
  */
 #ifdef DEBUG
-#if 0 /* DC21285-type */
+#if defined(CONFIG_DEBUG_DC21285_PORT)
 		.macro	loadsp,	rb
 		mov	\rb, #0x7c000000
 		.endm
 		.macro	writeb,	rb
 		strb	\rb, [r3, #0x3f8]
 		.endm
-#elif 0 /* RiscPC-type */
+#elif defined(CONFIG_ARCH_RPC)
 		.macro	loadsp,	rb
 		mov	\rb, #0x03000000
 		orr	\rb, \rb, #0x00010000
@@ -33,13 +33,25 @@
 		.macro	writeb,	rb
 		strb	\rb, [r3, #0x3f8 << 2]
 		.endm
-#elif 0 /* integrator-type */
+#elif defined(CONFIG_ARCH_INTEGRATOR)
 		.macro	loadsp, rb
 		mov	\rb, #0x16000000
 		.endm
 		.macro	writeb, rb
 		strb	\rb, [r3, #0]
 		.endm
+#elif defined(CONFIG_ARCH_SA1100)
+		.macro	loadsp, rb
+		mov	\rb, #0x80000000	@ physical base address
+#  if defined(CONFIG_DEBUG_LL_SER3)
+		add	\rb, \rb, #0x00050000	@ Ser3
+#  else
+		add	\rb, \rb, #0x00010000	@ Ser1
+#  endif
+		.endm
+		.macro	writeb, rb
+		str	\rb, [r3, #0x14]	@ UTDR
+		.endm
 #else
 #error no serial architecture defined
 #endif
@@ -64,7 +76,7 @@
 		kphex	r7, 8		/* architecture id */
 		kputc	#':'
 		mrc	p15, 0, r0, c1, c0
-		kphex	r0, 8		/* control reg
+		kphex	r0, 8		/* control reg */
 		kputc	#'\n'
 		kphex	r5, 8		/* decompressed kernel start */
 		kputc	#'-'
@@ -218,7 +230,8 @@
 		ldr     r1, proc_sa1110_type
 		eor	r1, r1, r6
 		movs	r1, r1, lsr #4
-		movne	pc, lr
+@		movne	pc, lr
+		bne	cache_off
 1:
 		sub	r3, r4, #16384		@ Page directory size
 		bic	r3, r3, #0xff		@ Align the pointer
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/boot/compressed/misc.c linux/arch/arm/boot/compressed/misc.c
--- linux.orig/arch/arm/boot/compressed/misc.c	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/boot/compressed/misc.c	Tue May 28 22:39:17 2002
@@ -18,6 +18,8 @@
 
 unsigned int __machine_arch_type;
 
+#include <linux/kernel.h>
+
 #include <asm/uaccess.h>
 #include <asm/arch/uncompress.h>
 #include <asm/proc/uncompress.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/boot/compressed/ofw-shark.c linux/arch/arm/boot/compressed/ofw-shark.c
--- linux.orig/arch/arm/boot/compressed/ofw-shark.c	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/boot/compressed/ofw-shark.c	Tue May 28 22:39:28 2002
@@ -1,7 +1,7 @@
 /*
  * linux/arch/arm/boot/compressed/ofw-shark.c
  *
- * by Alexander Schulz <aschulz@netwinder.org>
+ * by Alexander Schulz
  *
  * This file is used to get some basic information
  * about the memory layout of the shark we are running
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/config.in linux/arch/arm/config.in
--- linux.orig/arch/arm/config.in	Fri Nov  9 21:58:02 2001
+++ linux/arch/arm/config.in	Tue May 28 22:39:19 2002
@@ -43,6 +43,7 @@
 	 FootBridge		CONFIG_ARCH_FOOTBRIDGE \
 	 Integrator		CONFIG_ARCH_INTEGRATOR \
 	 LinkUp-L7200		CONFIG_ARCH_L7200 \
+	 Motorola-MX1ADS        CONFIG_ARCH_MX1ADS \
 	 RiscPC			CONFIG_ARCH_RPC \
  	 SA1100-based		CONFIG_ARCH_SA1100 \
 	 Shark			CONFIG_ARCH_SHARK" RiscPC
@@ -85,7 +86,14 @@
          32MB   CONFIG_SA1100_CERF_FLASH_32MB" CerfFlash
    bool 'Cerf w/CPLD support (CerfPDA)' CONFIG_SA1100_CERF_CPLD
 fi
-dep_bool '  Compaq iPAQ H3600' CONFIG_SA1100_H3600 $CONFIG_ARCH_SA1100
+dep_bool '  Compaq iPAQ H3100' CONFIG_SA1100_H3100 $CONFIG_ARCH_SA1100
+dep_bool '  Compaq iPAQ H3600/H3700' CONFIG_SA1100_H3600 $CONFIG_ARCH_SA1100
+dep_bool '  Compaq iPAQ H3800' CONFIG_SA1100_H3800 $CONFIG_ARCH_SA1100
+if [ "$CONFIG_SA1100_H3100" = "y" -o "$CONFIG_SA1100_H3600" = "y" -o "$CONFIG_SA1100_H3800" = "y" ]; then
+  define_bool CONFIG_SA1100_H3XXX y
+else
+  define_bool CONFIG_SA1100_H3XXX n
+fi
 #dep_bool '  Empeg' CONFIG_SA1100_EMPEG $CONFIG_ARCH_SA1100
 dep_bool '  Extenex HandHeld Theater (Squashtail)' CONFIG_SA1100_EXTENEX1 $CONFIG_ARCH_SA1100
 if [ "$CONFIG_SA1100_EXTENEX1" = "y" ]; then
@@ -93,8 +101,10 @@
 fi
 dep_bool '  FlexaNet' CONFIG_SA1100_FLEXANET $CONFIG_ARCH_SA1100
 dep_bool '  FreeBird-v1.1' CONFIG_SA1100_FREEBIRD $CONFIG_ARCH_SA1100
+dep_bool '  Frodo' CONFIG_SA1100_FRODO $CONFIG_ARCH_SA1100
 dep_bool '  GraphicsClient Plus' CONFIG_SA1100_GRAPHICSCLIENT $CONFIG_ARCH_SA1100
 dep_bool '  GraphicsMaster' CONFIG_SA1100_GRAPHICSMASTER $CONFIG_ARCH_SA1100
+dep_bool '  HP Labs BadgePAD 4' CONFIG_SA1100_BADGE4 $CONFIG_ARCH_SA1100
 dep_bool '  HP Jornada 720' CONFIG_SA1100_JORNADA720 $CONFIG_ARCH_SA1100
 dep_bool '  HuW WebPanel' CONFIG_SA1100_HUW_WEBPANEL $CONFIG_ARCH_SA1100
 dep_bool '  Itsy' CONFIG_SA1100_ITSY $CONFIG_ARCH_SA1100
@@ -103,6 +113,8 @@
 dep_bool '  OmniMeter' CONFIG_SA1100_OMNIMETER $CONFIG_ARCH_SA1100
 dep_bool '  Pangolin' CONFIG_SA1100_PANGOLIN $CONFIG_ARCH_SA1100
 dep_bool '  PLEB' CONFIG_SA1100_PLEB $CONFIG_ARCH_SA1100
+dep_bool '  PT System 3' CONFIG_SA1100_PT_SYSTEM3 $CONFIG_ARCH_SA1100
+dep_bool '  Shannon' CONFIG_SA1100_SHANNON $CONFIG_ARCH_SA1100
 dep_bool '  Sherman' CONFIG_SA1100_SHERMAN $CONFIG_ARCH_SA1100
 dep_bool '  Simpad' CONFIG_SA1100_SIMPAD $CONFIG_ARCH_SA1100
 dep_bool '  Tulsa' CONFIG_SA1100_PFS168 $CONFIG_ARCH_SA1100
@@ -116,18 +128,28 @@
      "$CONFIG_SA1100_PFS168" = "y" -o \
      "$CONFIG_SA1100_XP860" = "y" -o \
      "$CONFIG_SA1100_GRAPHICSMASTER" = "y" -o \
-     "$CONFIG_SA1100_ADSBITSY" = "y" ]; then
+     "$CONFIG_SA1100_PT_SYSTEM3" = "y" -o \
+     "$CONFIG_SA1100_ADSBITSY" = "y" -o \
+     "$CONFIG_SA1100_BADGE4" = "y" ]; then
    define_bool CONFIG_SA1111 y
    define_int CONFIG_FORCE_MAX_ZONEORDER 9
 fi
+
+#dep_tristate 'SA1100 USB function support' CONFIG_SA1100_USB $CONFIG_ARCH_SA1100
+#dep_tristate '  Support for SA11x0 USB network link function' CONFIG_SA1100_USB_NETLINK $CONFIG_SA1100_USB
+#dep_tristate '  Support for SA11x0 USB character device emulation' CONFIG_SA1100_USB_CHAR $CONFIG_SA1100_USB
+
+dep_tristate 'Compaq iPAQ Handheld sleeve support' CONFIG_H3600_SLEEVE $CONFIG_SA1100_H3600
 endmenu
 
 mainmenu_option next_comment
 comment 'CLPS711X/EP721X Implementations'
+dep_bool '  AUTCPU12' CONFIG_ARCH_AUTCPU12 $CONFIG_ARCH_CLPS711X
 dep_bool '  CDB89712' CONFIG_ARCH_CDB89712 $CONFIG_ARCH_CLPS711X
 dep_bool '  CLEP7312' CONFIG_ARCH_CLEP7312 $CONFIG_ARCH_CLPS711X
 dep_bool '  EDB7211' CONFIG_ARCH_EDB7211 $CONFIG_ARCH_CLPS711X
 dep_bool '  P720T' CONFIG_ARCH_P720T $CONFIG_ARCH_CLPS711X
+dep_bool '  FORTUNET' CONFIG_ARCH_FORTUNET $CONFIG_ARCH_CLPS711X
 
 # XXX Maybe these should indicate register compatibility
 # instead of being mutually exclusive.
@@ -205,7 +227,7 @@
      "$CONFIG_ARCH_NEXUSPCI"   = "y" -o "$CONFIG_ARCH_CLPS711X" = "y" -o \
      "$CONFIG_ARCH_INTEGRATOR" = "y" -o "$CONFIG_ARCH_SA1100"   = "y" -o \
      "$CONFIG_ARCH_L7200"      = "y" -o "$CONFIG_ARCH_ANAKIN"	= "y" -o \
-     "$CONFIG_ARCH_CAMELOT"    = "y" ]; then
+     "$CONFIG_ARCH_CAMELOT"    = "y" -o "$CONFIG_ARCH_MX1ADS"   = "y" ]; then
    define_bool CONFIG_CPU_32v4 y
 else
    define_bool CONFIG_CPU_32v4 n
@@ -247,11 +269,17 @@
 fi
 
 # ARM920T
-if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
-   bool 'Support ARM920T processor' CONFIG_CPU_ARM920T
+if [ "$CONFIG_ARCH_MX1ADS" = "y" ]; then
+   define_bool CONFIG_CPU_ARM920T y
 else
-   define_bool CONFIG_CPU_ARM920T n
+   if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
+      bool 'Support ARM920T processor' CONFIG_CPU_ARM920T
+   else
+      define_bool CONFIG_CPU_ARM920T n
+   fi
 fi
+
+
 if [ "$CONFIG_CPU_ARM920T" = "y" ]; then
    bool '  ARM920T CPU idle' CONFIG_CPU_ARM920_CPU_IDLE
    bool '  ARM920T I-Cache on' CONFIG_CPU_ARM920_I_CACHE_ON
@@ -261,6 +289,21 @@
    fi
 fi
 
+# ARM922T
+if [ "$CONFIG_ARCH_CAMELOT" = "y" ]; then
+         define_bool CONFIG_CPU_ARM922T y
+else
+         define_bool CONFIG_CPU_ARM922T n
+fi
+if [ "$CONFIG_CPU_ARM922T" = "y" ]; then
+   bool '  ARM922T CPU idle' CONFIG_CPU_ARM922_CPU_IDLE
+   bool '  ARM922T I-Cache on' CONFIG_CPU_ARM922_I_CACHE_ON
+   bool '  ARM922T D-Cache on' CONFIG_CPU_ARM922_D_CACHE_ON
+   if [ "$CONFIG_CPU_ARM922_D_CACHE_ON" = "y" ] ; then
+      bool '  Force write through caches on ARM922T' CONFIG_CPU_ARM922_WRITETHROUGH
+   fi
+fi
+
 # ARM926T
 if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
    bool 'Support ARM926T processor' CONFIG_CPU_ARM926T
@@ -404,7 +447,8 @@
      "$CONFIG_ARCH_P720T" = "y" -o	     \
      "$CONFIG_ARCH_CDB89712" = "y" -o	     \
      "$CONFIG_ARCH_CAMELOT" = "y" -o	     \
-     "$CONFIG_ARCH_ANAKIN" = "y" ]; then
+     "$CONFIG_ARCH_ANAKIN" = "y"  -o         \
+     "$CONFIG_ARCH_MX1ADS" = "y" ]; then
    string 'Default kernel command string' CONFIG_CMDLINE ""
 fi
 if [ "$CONFIG_ARCH_NETWINDER" = "y" -o  \
@@ -554,7 +598,8 @@
         "$CONFIG_ARCH_TBOX" = "y" -o       \
         "$CONFIG_ARCH_CLPS7500" = "y" -o   \
         "$CONFIG_ARCH_P720T" = "y" -o      \
-        "$CONFIG_ARCH_ANAKIN" = "y" ]; then
+        "$CONFIG_ARCH_ANAKIN" = "y" -o      \
+	"$CONFIG_ARCH_MX1ADS" = "y" ]; then
       define_bool CONFIG_PC_KEYMAP y
    fi
    if [ "$CONFIG_ARCH_ACORN" != "y" -a "$CONFIG_ARCH_EBSA110" != "y" ]; then
@@ -584,25 +629,29 @@
 
 source drivers/usb/Config.in
 
-if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-   source net/bluetooth/Config.in
-fi
+source net/bluetooth/Config.in
 
 mainmenu_option next_comment
 comment 'Kernel hacking'
 
-# Always compile kernel with framepointer (until 2.4 real comes out)
-# Bug reports aren't much use without this.
-bool 'Compile kernel without frame pointer' CONFIG_NO_FRAME_POINTER
-bool 'Verbose kernel error messages' CONFIG_DEBUG_ERRORS
+# RMK wants arm kernels compiled with frame pointers so hardwire this to y.  If
+# you know what you are doing and are willing to live without stack traces, you
+# can get a slightly smaller kernel by setting this option to n, but then RMK
+# will have to kill you ;).
+define_bool CONFIG_FRAME_POINTER y
 bool 'Verbose user fault messages' CONFIG_DEBUG_USER
 bool 'Include debugging information in kernel binary' CONFIG_DEBUG_INFO
-bool 'Debug memory allocations' CONFIG_DEBUG_SLAB
-bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
-bool 'Spinlock debugging' CONFIG_DEBUG_SPINLOCK
 dep_bool 'Disable pgtable cache' CONFIG_NO_PGT_CACHE $CONFIG_CPU_26
+
+bool 'Kernel debugging' CONFIG_DEBUG_KERNEL
+dep_bool '  Debug memory allocations' CONFIG_DEBUG_SLAB $CONFIG_DEBUG_KERNEL
+dep_bool '  Magic SysRq key' CONFIG_MAGIC_SYSRQ $CONFIG_DEBUG_KERNEL
+dep_bool '  Spinlock debugging' CONFIG_DEBUG_SPINLOCK $CONFIG_DEBUG_KERNEL
+dep_bool '  Wait queue debugging' CONFIG_DEBUG_WAITQ $CONFIG_DEBUG_KERNEL
+dep_bool '  Verbose BUG() reporting (adds 70K)' CONFIG_DEBUG_BUGVERBOSE $CONFIG_DEBUG_KERNEL
+dep_bool '  Verbose kernel error messages' CONFIG_DEBUG_ERRORS $CONFIG_DEBUG_KERNEL
 # These options are only for real kernel hackers who want to get their hands dirty. 
-dep_bool 'Kernel low-level debugging functions' CONFIG_DEBUG_LL $CONFIG_EXPERIMENTAL
-dep_bool '  Kernel low-level debugging messages via footbridge serial port' CONFIG_DEBUG_DC21285_PORT $CONFIG_DEBUG_LL $CONFIG_FOOTBRIDGE
-dep_bool '  kernel low-level debugging messages via UART2' CONFIG_DEBUG_CLPS711X_UART2 $CONFIG_DEBUG_LL $CONFIG_ARCH_CLPS711X
+dep_bool '  Kernel low-level debugging functions' CONFIG_DEBUG_LL $CONFIG_DEBUG_KERNEL
+dep_bool '    Kernel low-level debugging messages via footbridge serial port' CONFIG_DEBUG_DC21285_PORT $CONFIG_DEBUG_LL $CONFIG_FOOTBRIDGE
+dep_bool '    Kernel low-level debugging messages via UART2' CONFIG_DEBUG_CLPS711X_UART2 $CONFIG_DEBUG_LL $CONFIG_ARCH_CLPS711X
 endmenu
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/def-configs/adsbitsy linux/arch/arm/def-configs/adsbitsy
--- linux.orig/arch/arm/def-configs/adsbitsy	Thu Oct 25 20:53:44 2001
+++ linux/arch/arm/def-configs/adsbitsy	Tue May 28 22:39:17 2002
@@ -663,7 +663,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 # CONFIG_DEBUG_USER is not set
 # CONFIG_DEBUG_INFO is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/def-configs/anakin linux/arch/arm/def-configs/anakin
--- linux.orig/arch/arm/def-configs/anakin	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/def-configs/anakin	Tue May 28 22:39:15 2002
@@ -454,7 +454,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/def-configs/assabet linux/arch/arm/def-configs/assabet
--- linux.orig/arch/arm/def-configs/assabet	Thu Oct 25 20:53:44 2001
+++ linux/arch/arm/def-configs/assabet	Tue May 28 22:39:23 2002
@@ -956,7 +956,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/def-configs/badge4 linux/arch/arm/def-configs/badge4
--- linux.orig/arch/arm/def-configs/badge4	Thu Jan  1 00:00:00 1970
+++ linux/arch/arm/def-configs/badge4	Tue May 28 22:39:21 2002
@@ -0,0 +1,1136 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODVERSIONS=y
+CONFIG_KMOD=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_RPC is not set
+CONFIG_ARCH_SA1100=y
+# CONFIG_ARCH_SHARK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+CONFIG_SA1100_BADGE4=y
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+CONFIG_SA1111=y
+CONFIG_FORCE_MAX_ZONEORDER=9
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_H3600_SLEEVE is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+
+#
+# Processor Type
+#
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_SA110 is not set
+CONFIG_CPU_SA1100=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_DISCONTIGMEM=y
+
+#
+# General setup
+#
+# CONFIG_PCI is not set
+CONFIG_ISA=y
+# CONFIG_ISA_DMA is not set
+CONFIG_CPU_FREQ=y
+CONFIG_HOTPLUG=y
+
+#
+# PCMCIA/CardBus support
+#
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_PROBE=y
+# CONFIG_I82092 is not set
+# CONFIG_I82365 is not set
+# CONFIG_TCIC is not set
+# CONFIG_PCMCIA_CLPS6700 is not set
+CONFIG_PCMCIA_SA1100=y
+CONFIG_NET=y
+# CONFIG_SYSVIPC is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+CONFIG_FPE_FASTFPE=m
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_AOUT=m
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_MISC=m
+# CONFIG_PM is not set
+CONFIG_ARTHUR=m
+CONFIG_CMDLINE="init=/linuxrc root=/dev/mtdblock3"
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=m
+# CONFIG_PARPORT_PC is not set
+# CONFIG_PARPORT_AMIGA is not set
+# CONFIG_PARPORT_MFC3 is not set
+# CONFIG_PARPORT_ATARI is not set
+# CONFIG_PARPORT_GSC is not set
+# CONFIG_PARPORT_SUNBPP is not set
+# CONFIG_PARPORT_OTHER is not set
+# CONFIG_PARPORT_1284 is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+CONFIG_MTD_DEBUG=y
+CONFIG_MTD_DEBUG_VERBOSE=0
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_BOOTLDR_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_CFI_B1 is not set
+CONFIG_MTD_CFI_B2=y
+# CONFIG_MTD_CFI_B4 is not set
+CONFIG_MTD_CFI_I1=y
+# CONFIG_MTD_CFI_I2 is not set
+# CONFIG_MTD_CFI_I4 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+CONFIG_MTD_RAM=y
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+CONFIG_MTD_SA1100=y
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD 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
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+# CONFIG_NET_ETHERNET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+CONFIG_NET_RADIO=y
+# CONFIG_STRIP is not set
+# CONFIG_WAVELAN is not set
+# CONFIG_ARLAN is not set
+# CONFIG_AIRONET4500 is not set
+# CONFIG_AIRONET4500_NONCS is not set
+# CONFIG_AIRONET4500_PROC is not set
+# CONFIG_AIRO is not set
+CONFIG_HERMES=y
+
+#
+# Wireless Pcmcia cards support
+#
+CONFIG_PCMCIA_HERMES=y
+CONFIG_AIRO_CS=m
+CONFIG_NET_WIRELESS=y
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=y
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_FMVJ18X=m
+CONFIG_PCMCIA_PCNET=y
+CONFIG_PCMCIA_AXNET=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_PCMCIA_SMC91C92=m
+CONFIG_PCMCIA_XIRC2PS=m
+# CONFIG_ARCNET_COM20020_CS is not set
+# CONFIG_PCMCIA_IBMTR is not set
+CONFIG_NET_PCMCIA_RADIO=y
+CONFIG_PCMCIA_RAYCS=m
+CONFIG_PCMCIA_NETWAVE=m
+CONFIG_PCMCIA_WAVELAN=m
+# CONFIG_AIRONET4500_CS is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+CONFIG_IRDA=y
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=y
+# CONFIG_IRNET is not set
+CONFIG_IRCOMM=y
+CONFIG_IRDA_ULTRA=y
+
+#
+# IrDA options
+#
+# CONFIG_IRDA_CACHE_LAST_LSAP is not set
+# CONFIG_IRDA_FAST_RR is not set
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+# CONFIG_IRTTY_SIR is not set
+# CONFIG_IRPORT_SIR is not set
+
+#
+# Dongle support
+#
+# CONFIG_DONGLE is not set
+
+#
+# FIR device drivers
+#
+# CONFIG_USB_IRDA is not set
+# CONFIG_NSC_FIR is not set
+# CONFIG_WINBOND_FIR is not set
+# CONFIG_TOSHIBA_FIR is not set
+# CONFIG_SMC_IRCC_FIR is not set
+# CONFIG_ALI_FIR is not set
+# CONFIG_VLSI_FIR is not set
+CONFIG_SA1100_FIR=y
+
+#
+# ATA/IDE/MFM/RLL support
+#
+CONFIG_IDE=m
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=m
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=m
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
+# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
+# CONFIG_BLK_DEV_IDEDISK_IBM is not set
+# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
+# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
+# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
+# CONFIG_BLK_DEV_IDEDISK_WD is not set
+# CONFIG_BLK_DEV_COMMERIAL is not set
+# CONFIG_BLK_DEV_TIVO is not set
+# CONFIG_BLK_DEV_IDECS is not set
+CONFIG_BLK_DEV_IDECD=m
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_BLK_DEV_IDEFLOPPY=m
+CONFIG_BLK_DEV_IDESCSI=m
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_DMA_NONPCI is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
+
+#
+# SCSI support
+#
+CONFIG_SCSI=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_SD_EXTRA_DEVS=40
+CONFIG_CHR_DEV_ST=m
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=m
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_SR_EXTRA_DEVS=2
+CONFIG_CHR_DEV_SG=y
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_DEBUG_QUEUES is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_SCSI_7000FASST is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AHA1542 is not set
+# CONFIG_SCSI_AHA1740 is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_AM53C974 is not set
+# CONFIG_SCSI_MEGARAID is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_EATA_DMA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_PPA is not set
+# CONFIG_SCSI_IMM is not set
+# CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PCI2000 is not set
+# CONFIG_SCSI_PCI2220I is not set
+# CONFIG_SCSI_PSI240I is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+# CONFIG_SCSI_PCMCIA is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+CONFIG_SERIAL_SA1100=y
+CONFIG_SERIAL_SA1100_CONSOLE=y
+CONFIG_SA1100_DEFAULT_BAUDRATE=115200
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+# CONFIG_PRINTER is not set
+# CONFIG_PPDEV is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_ALGOBIT=m
+# CONFIG_I2C_PHILIPSPAR is not set
+CONFIG_I2C_ELV=m
+CONFIG_I2C_VELLEMAN=m
+# CONFIG_I2C_BIT_SA1100_GPIO is not set
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ELEKTOR=m
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_PROC=m
+
+#
+# L3 serial bus support
+#
+CONFIG_L3=y
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+CONFIG_L3_SA1111=y
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+CONFIG_SOFT_WATCHDOG=m
+# CONFIG_WDT is not set
+# CONFIG_WDTPCI is not set
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+# CONFIG_21285_WATCHDOG is not set
+# CONFIG_977_WATCHDOG is not set
+CONFIG_SA1100_WATCHDOG=m
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+# CONFIG_I810_TCO is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_W83877F_WDT is not set
+# CONFIG_MACHZ_WDT is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+CONFIG_RTC=m
+CONFIG_SA1100_RTC=m
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+
+#
+# Multimedia devices
+#
+CONFIG_VIDEO_DEV=y
+
+#
+# Video For Linux
+#
+CONFIG_VIDEO_PROC_FS=y
+# CONFIG_I2C_PARPORT is not set
+
+#
+# Video Adapters
+#
+# CONFIG_VIDEO_BT848 is not set
+# CONFIG_VIDEO_PMS is not set
+# CONFIG_VIDEO_BWQCAM is not set
+# CONFIG_VIDEO_CQCAM is not set
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_TUNER_3036 is not set
+# CONFIG_VIDEO_STRADIS is not set
+# CONFIG_VIDEO_ZORAN is not set
+# CONFIG_VIDEO_ZORAN_BUZ is not set
+# CONFIG_VIDEO_ZORAN_DC10 is not set
+# CONFIG_VIDEO_ZORAN_LML33 is not set
+# CONFIG_VIDEO_ZR36120 is not set
+# CONFIG_VIDEO_MEYE is not set
+# CONFIG_VIDEO_CYBERPRO is not set
+
+#
+# Radio Adapters
+#
+# CONFIG_RADIO_CADET is not set
+# CONFIG_RADIO_RTRACK is not set
+# CONFIG_RADIO_RTRACK2 is not set
+# CONFIG_RADIO_AZTECH is not set
+# CONFIG_RADIO_GEMTEK is not set
+# CONFIG_RADIO_GEMTEK_PCI is not set
+# CONFIG_RADIO_MAXIRADIO is not set
+# CONFIG_RADIO_MAESTRO is not set
+# CONFIG_RADIO_MIROPCM20 is not set
+# CONFIG_RADIO_MIROPCM20_RDS is not set
+# CONFIG_RADIO_SF16FMI is not set
+# CONFIG_RADIO_TERRATEC is not set
+# CONFIG_RADIO_TRUST is not set
+# CONFIG_RADIO_TYPHOON is not set
+# CONFIG_RADIO_ZOLTRIX is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+CONFIG_EXT3_FS=m
+CONFIG_JBD=m
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+# CONFIG_UMSDOS_FS is not set
+CONFIG_VFAT_FS=m
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_CRAMFS=m
+CONFIG_TMPFS=y
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+CONFIG_MINIX_FS=m
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+CONFIG_DEVFS_FS=y
+CONFIG_DEVFS_MOUNT=y
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=m
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=m
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+CONFIG_ZLIB_FS_INFLATE=m
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+CONFIG_SMB_NLS=y
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_MIDI_EMU10K1 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_RME96XX is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_MIDI_VIA82CXXX is not set
+CONFIG_SOUND_SA1100=y
+CONFIG_SOUND_UDA1341=y
+# CONFIG_SOUND_ASSABET_UDA1341 is not set
+# CONFIG_SOUND_H3600_UDA1341 is not set
+# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
+CONFIG_SOUND_SA1111_UDA1341=y
+# CONFIG_SOUND_SA1100SSP is not set
+# CONFIG_SOUND_OSS is not set
+# CONFIG_SOUND_WAVEARTIST is not set
+# CONFIG_SOUND_TVMIXER is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+CONFIG_MCP=y
+CONFIG_MCP_SA1100=y
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_LONG_TIMEOUT is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+CONFIG_USB_OHCI_SA1111=y
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_AUDIO=y
+CONFIG_USB_BLUETOOTH=m
+CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE_DEBUG=y
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+#   Input core support is needed for USB HID
+#
+
+#
+# USB Imaging devices
+#
+CONFIG_USB_DC2XX=m
+CONFIG_USB_MDC800=m
+CONFIG_USB_SCANNER=m
+CONFIG_USB_MICROTEK=m
+CONFIG_USB_HPUSBSCSI=m
+
+#
+# USB Multimedia devices
+#
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_OV511=m
+CONFIG_USB_PWC=m
+CONFIG_USB_SE401=m
+# CONFIG_USB_STV680 is not set
+CONFIG_USB_VICAM=m
+CONFIG_USB_DSBR=m
+CONFIG_USB_DABUSB=m
+
+#
+# USB Network adaptors
+#
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_CATC=m
+CONFIG_USB_CDCETHER=m
+CONFIG_USB_USBNET=m
+
+#
+# USB port drivers
+#
+CONFIG_USB_USS720=m
+
+#
+# USB Serial Converter support
+#
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_BELKIN=m
+CONFIG_USB_SERIAL_WHITEHEAT=m
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
+CONFIG_USB_SERIAL_EMPEG=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_VISOR=m
+# CONFIG_USB_SERIAL_IPAQ is not set
+CONFIG_USB_SERIAL_IR=m
+CONFIG_USB_SERIAL_EDGEPORT=m
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+CONFIG_USB_SERIAL_MCT_U232=m
+# CONFIG_USB_SERIAL_KLSI is not set
+CONFIG_USB_SERIAL_PL2303=m
+CONFIG_USB_SERIAL_CYBERJACK=m
+CONFIG_USB_SERIAL_XIRCOM=m
+CONFIG_USB_SERIAL_OMNINET=m
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_RIO500=m
+
+#
+# Bluetooth support
+#
+CONFIG_BLUEZ=m
+CONFIG_BLUEZ_L2CAP=m
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BLUEZ_HCIUSB=m
+CONFIG_BLUEZ_HCIUART=m
+CONFIG_BLUEZ_HCIVHCI=m
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_NO_PGT_CACHE is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/def-configs/cerfcube linux/arch/arm/def-configs/cerfcube
--- linux.orig/arch/arm/def-configs/cerfcube	Thu Oct 25 20:53:44 2001
+++ linux/arch/arm/def-configs/cerfcube	Tue May 28 22:39:13 2002
@@ -876,7 +876,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/def-configs/cerfpda linux/arch/arm/def-configs/cerfpda
--- linux.orig/arch/arm/def-configs/cerfpda	Thu Oct 25 20:53:44 2001
+++ linux/arch/arm/def-configs/cerfpda	Tue May 28 22:39:18 2002
@@ -970,7 +970,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/def-configs/cerfpod linux/arch/arm/def-configs/cerfpod
--- linux.orig/arch/arm/def-configs/cerfpod	Thu Oct 25 20:53:44 2001
+++ linux/arch/arm/def-configs/cerfpod	Tue May 28 22:39:26 2002
@@ -897,7 +897,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/def-configs/clps7500 linux/arch/arm/def-configs/clps7500
--- linux.orig/arch/arm/def-configs/clps7500	Sun May 20 00:43:05 2001
+++ linux/arch/arm/def-configs/clps7500	Tue May 28 22:39:13 2002
@@ -511,7 +511,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 # CONFIG_DEBUG_ERRORS is not set
 # CONFIG_DEBUG_USER is not set
 # CONFIG_DEBUG_INFO is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/def-configs/ebsa110 linux/arch/arm/def-configs/ebsa110
--- linux.orig/arch/arm/def-configs/ebsa110	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/def-configs/ebsa110	Tue May 28 22:39:14 2002
@@ -594,7 +594,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 # CONFIG_DEBUG_USER is not set
 # CONFIG_DEBUG_INFO is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/def-configs/epxa10db linux/arch/arm/def-configs/epxa10db
--- linux.orig/arch/arm/def-configs/epxa10db	Thu Oct 25 20:53:44 2001
+++ linux/arch/arm/def-configs/epxa10db	Tue May 28 22:39:21 2002
@@ -651,7 +651,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_INFO=y
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/def-configs/flexanet linux/arch/arm/def-configs/flexanet
--- linux.orig/arch/arm/def-configs/flexanet	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/def-configs/flexanet	Tue May 28 22:39:25 2002
@@ -8,6 +8,8 @@
 CONFIG_UID16=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
 
 #
 # Code maturity level options
@@ -25,17 +27,19 @@
 #
 # System Type
 #
+# CONFIG_ARCH_ANAKIN is not set
 # CONFIG_ARCH_ARCA5K is not set
 # CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_L7200 is not set
 # CONFIG_ARCH_RPC is not set
 CONFIG_ARCH_SA1100=y
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_SHARK is not set
 
 #
 # Archimedes/A5000 Implementations
@@ -44,22 +48,32 @@
 #
 # Archimedes/A5000 Implementations (select only ONE)
 #
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
 
 #
 # Footbridge Implementations
 #
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
 
 #
 # SA11x0 Implementations
 #
 # CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSBITSY is not set
 # CONFIG_SA1100_BRUTUS is not set
 # CONFIG_SA1100_CERF is not set
-# CONFIG_SA1100_BITSY is not set
+# CONFIG_SA1100_H3600 is not set
 # CONFIG_SA1100_EXTENEX1 is not set
 CONFIG_SA1100_FLEXANET=y
 # CONFIG_SA1100_FREEBIRD is not set
 # CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
 # CONFIG_SA1100_JORNADA720 is not set
 # CONFIG_SA1100_HUW_WEBPANEL is not set
 # CONFIG_SA1100_ITSY is not set
@@ -68,7 +82,9 @@
 # CONFIG_SA1100_OMNIMETER is not set
 # CONFIG_SA1100_PANGOLIN is not set
 # CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_SHANNON is not set
 # CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
 # CONFIG_SA1100_PFS168 is not set
 # CONFIG_SA1100_VICTOR is not set
 # CONFIG_SA1100_XP860 is not set
@@ -76,11 +92,17 @@
 CONFIG_SA1100_USB=y
 CONFIG_SA1100_USB_NETLINK=y
 # CONFIG_SA1100_USB_CHAR is not set
-# CONFIG_SA1100_FREQUENCY_SCALE is not set
 
 #
 # CLPS711X/EP721X Implementations
 #
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
 # CONFIG_ARCH_ACORN is not set
 # CONFIG_FOOTBRIDGE is not set
 # CONFIG_FOOTBRIDGE_HOST is not set
@@ -97,32 +119,40 @@
 # CONFIG_CPU_ARM710 is not set
 # CONFIG_CPU_ARM720T is not set
 # CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_CPU_ARM926T is not set
 # CONFIG_CPU_ARM1020 is not set
 # CONFIG_CPU_SA110 is not set
 CONFIG_CPU_SA1100=y
+# CONFIG_ARM_THUMB is not set
 CONFIG_DISCONTIGMEM=y
-# CONFIG_CPU_BIG_ENDIAN is not set
 
 #
 # General setup
 #
 # CONFIG_PCI is not set
-# CONFIG_ISA is not set
+CONFIG_ISA=y
 # CONFIG_ISA_DMA is not set
-# CONFIG_CPU_CLOCK is not set
+CONFIG_CPU_FREQ=y
 CONFIG_HOTPLUG=y
 
 #
 # PCMCIA/CardBus support
 #
 CONFIG_PCMCIA=y
+# CONFIG_I82092 is not set
 # CONFIG_I82365 is not set
 # CONFIG_TCIC is not set
+# CONFIG_PCMCIA_CLPS6700 is not set
 CONFIG_PCMCIA_SA1100=y
 CONFIG_NET=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
 CONFIG_FPE_NWFPE=y
 CONFIG_FPE_FASTFPE=y
 CONFIG_KCORE_ELF=y
@@ -130,7 +160,7 @@
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
-# CONFIG_PM is not set
+CONFIG_PM=y
 # CONFIG_ARTHUR is not set
 CONFIG_CMDLINE=""
 CONFIG_LEDS=y
@@ -149,7 +179,7 @@
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_REDBOOT_PARTS=y
 # CONFIG_MTD_BOOTLDR_PARTS is not set
 # CONFIG_MTD_AFS_PARTS is not set
 
@@ -165,43 +195,42 @@
 # RAM/ROM/Flash chip drivers
 #
 CONFIG_MTD_CFI=y
-# CONFIG_MTD_CFI_VIRTUAL_ER is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
 CONFIG_MTD_CFI_ADV_OPTIONS=y
 CONFIG_MTD_CFI_NOSWAP=y
 # CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
 # CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
-# CONFIG_MTD_CFI_LART_BIT_SWAP is not set
 # CONFIG_MTD_CFI_GEOMETRY is not set
 CONFIG_MTD_CFI_INTELEXT=y
 # CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_AMDSTD is not set
-# CONFIG_MTD_SHARP is not set
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
 # CONFIG_MTD_JEDEC is not set
 
 #
 # Mapping drivers for chip access
 #
 # CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_SUN_UFLASH is not set
 # 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_NETSC520 is not set
-# CONFIG_MTD_SBC_GXX is not set
-# CONFIG_MTD_ELAN_104NC is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
 CONFIG_MTD_SA1100=y
+# CONFIG_MTD_DC21285 is not set
 # CONFIG_MTD_IQ80310 is not set
-# CONFIG_MTD_CFI_FLAGADM is not set
-# CONFIG_MTD_ARMFLASH is not set
+# CONFIG_MTD_PCI is not set
 
 #
 # Self-contained MTD device drivers
 #
+# CONFIG_MTD_PMC551 is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
 
 #
 # Disk-On-Chip Device Drivers
@@ -220,11 +249,17 @@
 # Plug and Play configuration
 #
 # CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
 
 #
 # Block devices
 #
 # CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
@@ -235,6 +270,13 @@
 # Multi-device support (RAID and LVM)
 #
 # CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
 
 #
 # Networking options
@@ -258,6 +300,7 @@
 # CONFIG_IPV6 is not set
 # CONFIG_KHTTPD is not set
 # CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
 
 #
 #
@@ -293,42 +336,75 @@
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
-# CONFIG_NET_SB1000 is not set
 
 #
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
 CONFIG_NET_VENDOR_SMC=y
 # CONFIG_WD80x3 is not set
+# CONFIG_ULTRAMCA is not set
 # CONFIG_ULTRA is not set
+# CONFIG_ULTRA32 is not set
 CONFIG_SMC9194=y
 # CONFIG_NET_VENDOR_RACAL is not set
 # CONFIG_AT1700 is not set
 # CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
 # CONFIG_NET_PCI is not set
 # CONFIG_NET_POCKET is not set
 
 #
 # Ethernet (1000 Mbit)
 #
-# CONFIG_ACENIC_OMIT_TIGON_I is not set
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
 
 #
 # Wireless LAN (non-hamradio)
 #
-# CONFIG_NET_RADIO is not set
+CONFIG_NET_RADIO=y
+# CONFIG_STRIP is not set
+# CONFIG_WAVELAN is not set
+# CONFIG_ARLAN is not set
+# CONFIG_AIRONET4500 is not set
+# CONFIG_AIRONET4500_NONCS is not set
+# CONFIG_AIRONET4500_PROC is not set
+# CONFIG_AIRO is not set
+CONFIG_HERMES=m
+
+#
+# Wireless Pcmcia cards support
+#
+CONFIG_PCMCIA_HERMES=m
+# CONFIG_AIRO_CS is not set
+CONFIG_NET_WIRELESS=y
 
 #
 # Token Ring devices
 #
 # CONFIG_TR is not set
 # CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
 # CONFIG_SHAPER is not set
 
 #
@@ -347,8 +423,10 @@
 # CONFIG_PCMCIA_NMCLAN is not set
 # CONFIG_PCMCIA_SMC91C92 is not set
 # CONFIG_PCMCIA_XIRC2PS is not set
+# CONFIG_PCMCIA_AXNET is not set
+# CONFIG_ARCNET_COM20020_CS is not set
+# CONFIG_PCMCIA_IBMTR is not set
 # CONFIG_NET_PCMCIA_RADIO is not set
-CONFIG_PCMCIA_NETCARD=y
 
 #
 # Amateur Radio support
@@ -378,20 +456,33 @@
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
 # CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
+# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
+# CONFIG_BLK_DEV_IDEDISK_IBM is not set
+# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
+# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
+# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
+# CONFIG_BLK_DEV_IDEDISK_WD is not set
 # CONFIG_BLK_DEV_COMMERIAL is not set
+# CONFIG_BLK_DEV_TIVO is not set
 CONFIG_BLK_DEV_IDECS=y
 # CONFIG_BLK_DEV_IDECD is not set
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
 
 #
 # IDE chipset support/bugfixes
 #
 # CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
 # CONFIG_IDE_CHIPSETS is not set
 # CONFIG_IDEDMA_AUTO is not set
 # CONFIG_DMA_NONPCI is not set
 # CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
 
 #
 # SCSI support
@@ -402,6 +493,10 @@
 # I2O device support
 #
 # CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
 
 #
 # ISDN subsystem
@@ -412,6 +507,10 @@
 # Input core support
 #
 # CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
 
 #
 # Character devices
@@ -419,21 +518,38 @@
 CONFIG_VT=y
 # CONFIG_VT_CONSOLE is not set
 # CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
 CONFIG_SERIAL_SA1100=y
-# CONFIG_SERIAL_SA1100_OLD is not set
 CONFIG_SERIAL_SA1100_CONSOLE=y
 CONFIG_SA1100_DEFAULT_BAUDRATE=57600
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=32
-CONFIG_UCB1200=y
-CONFIG_TOUCHSCREEN_UCB1200=y
-CONFIG_AUDIO_UCB1200=y
-CONFIG_ADC_UCB1200=y
-# CONFIG_TOUCHSCREEN_BITSY is not set
-# CONFIG_PROFILER is not set
 
 #
 # I2C support
@@ -441,37 +557,35 @@
 # CONFIG_I2C is not set
 
 #
-# Mice
+# L3 serial bus support
 #
-# CONFIG_BUSMOUSE is not set
-# CONFIG_MOUSE is not set
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
 
 #
-# Joysticks
+# Other L3 adapters
 #
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
 
 #
-# Game port support
-#
-
-#
-# Gameport joysticks
-#
-
-#
-# Serial port support
+# Mice
 #
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
 
 #
-# Serial port joysticks
+# Joysticks
 #
+# CONFIG_INPUT_GAMEPORT is not set
 
 #
-# Parallel port joysticks
+# Input core support is needed for gameports
 #
 
 #
-#   Parport support is needed for parallel port joysticks
+# Input core support is needed for joysticks
 #
 # CONFIG_QIC02_TAPE is not set
 
@@ -479,6 +593,7 @@
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
 CONFIG_SA1100_RTC=y
@@ -509,44 +624,74 @@
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
 # CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
-# CONFIG_JFFS2_FS is not set
-CONFIG_CRAMFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+# CONFIG_CRAMFS is not set
 # CONFIG_TMPFS is not set
 CONFIG_RAMFS=y
 # CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
 CONFIG_PROC_FS=y
 # CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
 CONFIG_DEVPTS_FS=y
 # CONFIG_QNX4FS_FS is not set
-CONFIG_ROMFS_FS=y
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
 CONFIG_EXT2_FS=y
 # CONFIG_SYSV_FS is not set
 # CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
 
 #
 # Network File Systems
 #
 # CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
 # CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
 
 #
 # Partition Types
@@ -562,6 +707,7 @@
 # CONFIG_MINIX_SUBPARTITION is not set
 # CONFIG_SOLARIS_X86_PARTITION is not set
 # CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
 # CONFIG_SGI_PARTITION is not set
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
@@ -573,15 +719,17 @@
 #
 CONFIG_PC_KEYMAP=y
 # CONFIG_VGA_CONSOLE is not set
-CONFIG_FB=y
 
 #
 # Frame-buffer support
 #
 CONFIG_FB=y
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_ACORN is not set
+# CONFIG_FB_ANAKIN is not set
+# CONFIG_FB_CLPS711X is not set
 CONFIG_FB_SA1100=y
-# CONFIG_FB_E1355 is not set
+# CONFIG_FB_CYBER2000 is not set
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FBCON_ADVANCED is not set
 CONFIG_FBCON_CFB2=y
@@ -597,28 +745,49 @@
 # Sound
 #
 CONFIG_SOUND=y
-# CONFIG_SOUND_SA1100_SSP is not set
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_MIDI_EMU10K1 is not set
 # CONFIG_SOUND_FUSION is not set
 # CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
 # CONFIG_SOUND_ESSSOLO1 is not set
 # CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_RME96XX is not set
 # CONFIG_SOUND_SONICVIBES is not set
 # CONFIG_SOUND_TRIDENT is not set
 # CONFIG_SOUND_MSNDCLAS is not set
 # CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_MIDI_VIA82CXXX is not set
+# CONFIG_SOUND_SA1100 is not set
+# CONFIG_SOUND_UDA1341 is not set
+# CONFIG_SOUND_ASSABET_UDA1341 is not set
+# CONFIG_SOUND_H3600_UDA1341 is not set
+# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
+# CONFIG_SOUND_SA1111_UDA1341 is not set
+# CONFIG_SOUND_SA1100SSP is not set
 # CONFIG_SOUND_OSS is not set
+# CONFIG_SOUND_WAVEARTIST is not set
+# CONFIG_SOUND_TVMIXER is not set
 
 #
-# USB support
+# Multimedia Capabilities Port drivers
 #
-CONFIG_USB=y
-CONFIG_USB_DEBUG=y
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
 
 #
-# Miscellaneous USB options
+# USB support
 #
-# CONFIG_USB_DEVICEFS is not set
-# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB is not set
 
 #
 # USB Controllers
@@ -626,15 +795,22 @@
 # CONFIG_USB_UHCI is not set
 # CONFIG_USB_UHCI_ALT is not set
 # CONFIG_USB_OHCI is not set
+# CONFIG_USB_OHCI_SA1111 is not set
 
 #
 # USB Device Class drivers
 #
 # CONFIG_USB_AUDIO is not set
 # CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_STORAGE is not set
 # CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
 # CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
 
@@ -652,40 +828,83 @@
 # CONFIG_USB_DC2XX is not set
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
 
 #
 # USB Multimedia devices
 #
-# CONFIG_USB_DABUSB is not set
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
 
 #
 # USB Network adaptors
 #
-# CONFIG_USB_PLUSB is not set
 # CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_NET1080 is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
 # CONFIG_USB_USBNET is not set
 
 #
 # USB port drivers
 #
+# CONFIG_USB_USS720 is not set
 
 #
 # USB Serial Converter support
 #
 # CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
 
 #
-# USB misc drivers
+# USB Miscellaneous drivers
 #
 # CONFIG_USB_RIO500 is not set
 
 #
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
-CONFIG_DEBUG_ERRORS=y
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
-CONFIG_MAGIC_SYSRQ=y
+# CONFIG_NO_PGT_CACHE is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
 # CONFIG_DEBUG_LL is not set
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/def-configs/fortunet linux/arch/arm/def-configs/fortunet
--- linux.orig/arch/arm/def-configs/fortunet	Thu Jan  1 00:00:00 1970
+++ linux/arch/arm/def-configs/fortunet	Tue May 28 22:39:14 2002
@@ -0,0 +1,593 @@
+#
+# Automatically generated by make menuconfig: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+CONFIG_ARCH_CLPS711X=y
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_SHARK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_H3600_SLEEVE is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_P720T is not set
+CONFIG_ARCH_FORTUNET=y
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+CONFIG_CPU_ARM720T=y
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_SA110 is not set
+# CONFIG_CPU_SA1100 is not set
+# CONFIG_ARM_THUMB is not set
+# CONFIG_DISCONTIGMEM is not set
+
+#
+# General setup
+#
+# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_FPE_NWFPE is not set
+CONFIG_FPE_FASTFPE=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_PARTITIONS is not set
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_BOOTLDR_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+# CONFIG_MTD_SA1100 is not set
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+CONFIG_MTD_FORTUNET=y
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+# CONFIG_INET is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET_AUNUDP is not set
+# CONFIG_ECONET_NATIVE is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network device support
+#
+# CONFIG_NETDEVICES is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Synchronous Serial Interface
+#
+# CONFIG_SSI is not set
+# CONFIG_SSI_CLPS711X is not set
+# CONFIG_SSI_JUNO is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+CONFIG_SERIAL_CLPS711X=y
+CONFIG_SERIAL_CLPS711X_CONSOLE=y
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+# CONFIG_SERIAL_SA1100 is not set
+# CONFIG_SERIAL_SA1100_CONSOLE is not set
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS_FS=y
+CONFIG_JFFS_FS_VERBOSE=0
+# CONFIG_JFFS_PROC_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+# CONFIG_NFS_FS is not set
+# CONFIG_NFS_V3 is not set
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_SUNRPC is not set
+# CONFIG_LOCKD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+# CONFIG_USB_OHCI_SA1111 is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_RIO500 is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
+# CONFIG_DEBUG_LL_SER3 is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/def-configs/freebird linux/arch/arm/def-configs/freebird
--- linux.orig/arch/arm/def-configs/freebird	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/def-configs/freebird	Tue May 28 22:39:18 2002
@@ -614,7 +614,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/def-configs/freebird_new linux/arch/arm/def-configs/freebird_new
--- linux.orig/arch/arm/def-configs/freebird_new	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/def-configs/freebird_new	Tue May 28 22:39:15 2002
@@ -634,7 +634,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 # CONFIG_DEBUG_USER is not set
 # CONFIG_DEBUG_INFO is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/def-configs/frodo linux/arch/arm/def-configs/frodo
--- linux.orig/arch/arm/def-configs/frodo	Thu Jan  1 00:00:00 1970
+++ linux/arch/arm/def-configs/frodo	Tue May 28 22:39:31 2002
@@ -0,0 +1,618 @@
+#
+# Automatically generated by make menuconfig: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_RPC is not set
+CONFIG_ARCH_SA1100=y
+# CONFIG_ARCH_SHARK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+CONFIG_SA1100_FRODO=y
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_H3600_SLEEVE is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_SA110 is not set
+CONFIG_CPU_SA1100=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_DISCONTIGMEM=y
+
+#
+# General setup
+#
+# CONFIG_PCI is not set
+CONFIG_ISA=y
+# CONFIG_ISA_DMA is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+# CONFIG_FPE_NWFPE is not set
+CONFIG_FPE_FASTFPE=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="console=ttySA0,9600 ramdisk_size=4096 root=/dev/ram idebus=33"
+CONFIG_LEDS=y
+CONFIG_LEDS_TIMER=y
+CONFIG_LEDS_CPU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network device support
+#
+# CONFIG_NETDEVICES is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
+# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
+# CONFIG_BLK_DEV_IDEDISK_IBM is not set
+# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
+# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
+# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
+# CONFIG_BLK_DEV_IDEDISK_WD is not set
+# CONFIG_BLK_DEV_COMMERIAL is not set
+# CONFIG_BLK_DEV_TIVO is not set
+# CONFIG_BLK_DEV_IDECS is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_DMA_NONPCI is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+CONFIG_SERIAL_SA1100=y
+CONFIG_SERIAL_SA1100_CONSOLE=y
+CONFIG_SA1100_DEFAULT_BAUDRATE=9600
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=16
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+CONFIG_SA1100_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+CONFIG_ROMFS_FS=y
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+# CONFIG_NFS_FS is not set
+# CONFIG_NFS_V3 is not set
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_SUNRPC is not set
+# CONFIG_LOCKD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Console drivers
+#
+CONFIG_PC_KEYMAP=y
+# CONFIG_VGA_CONSOLE is not set
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_ACORN is not set
+# CONFIG_FB_ANAKIN is not set
+# CONFIG_FB_CLPS711X is not set
+CONFIG_FB_SA1100=y
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_CFB2=y
+CONFIG_FBCON_CFB4=y
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
+# CONFIG_FBCON_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+# CONFIG_USB_OHCI_SA1111 is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_RIO500 is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_NO_PGT_CACHE is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SLAB=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_WAITQ=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/def-configs/graphicsclient linux/arch/arm/def-configs/graphicsclient
--- linux.orig/arch/arm/def-configs/graphicsclient	Thu Oct 25 20:53:44 2001
+++ linux/arch/arm/def-configs/graphicsclient	Tue May 28 22:39:28 2002
@@ -731,7 +731,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/def-configs/graphicsmaster linux/arch/arm/def-configs/graphicsmaster
--- linux.orig/arch/arm/def-configs/graphicsmaster	Thu Oct 25 20:53:44 2001
+++ linux/arch/arm/def-configs/graphicsmaster	Tue May 28 22:39:12 2002
@@ -744,7 +744,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/def-configs/h3600 linux/arch/arm/def-configs/h3600
--- linux.orig/arch/arm/def-configs/h3600	Thu Oct 25 20:53:44 2001
+++ linux/arch/arm/def-configs/h3600	Tue May 28 22:39:20 2002
@@ -948,7 +948,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 # CONFIG_DEBUG_USER is not set
 # CONFIG_DEBUG_INFO is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/def-configs/integrator linux/arch/arm/def-configs/integrator
--- linux.orig/arch/arm/def-configs/integrator	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/def-configs/integrator	Tue May 28 22:39:16 2002
@@ -652,7 +652,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/def-configs/jornada720 linux/arch/arm/def-configs/jornada720
--- linux.orig/arch/arm/def-configs/jornada720	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/def-configs/jornada720	Tue May 28 22:39:20 2002
@@ -1,11 +1,15 @@
 #
-# Automatically generated make config: don't edit
+# Automatically generated by make menuconfig: don't edit
 #
 CONFIG_ARM=y
 # CONFIG_EISA is not set
 # CONFIG_SBUS is not set
 # CONFIG_MCA is not set
 CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
 
 #
 # Code maturity level options
@@ -23,24 +27,23 @@
 #
 # System Type
 #
+# CONFIG_ARCH_ANAKIN is not set
 # CONFIG_ARCH_ARCA5K is not set
 # CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_CAMELOT is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_L7200 is not set
 # CONFIG_ARCH_RPC is not set
 CONFIG_ARCH_SA1100=y
-# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_SHARK is not set
 
 #
 # Archimedes/A5000 Implementations
 #
-
-#
-# Archimedes/A5000 Implementations (select only ONE)
-#
 # CONFIG_ARCH_ARC is not set
 # CONFIG_ARCH_A5K is not set
 
@@ -58,12 +61,18 @@
 #
 # CONFIG_SA1100_ASSABET is not set
 # CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSBITSY is not set
 # CONFIG_SA1100_BRUTUS is not set
 # CONFIG_SA1100_CERF is not set
-# CONFIG_SA1100_BITSY is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
 # CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
 # CONFIG_SA1100_FREEBIRD is not set
 # CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
 CONFIG_SA1100_JORNADA720=y
 # CONFIG_SA1100_HUW_WEBPANEL is not set
 # CONFIG_SA1100_ITSY is not set
@@ -72,70 +81,75 @@
 # CONFIG_SA1100_OMNIMETER is not set
 # CONFIG_SA1100_PANGOLIN is not set
 # CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_SHANNON is not set
 # CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
 # CONFIG_SA1100_PFS168 is not set
 # CONFIG_SA1100_VICTOR is not set
 # CONFIG_SA1100_XP860 is not set
 # CONFIG_SA1100_YOPY is not set
 CONFIG_SA1111=y
+CONFIG_FORCE_MAX_ZONEORDER=9
 # CONFIG_SA1100_USB is not set
 # CONFIG_SA1100_USB_NETLINK is not set
 # CONFIG_SA1100_USB_CHAR is not set
-# CONFIG_SA1100_FREQUENCY_SCALE is not set
-# CONFIG_SA1100_VOLTAGE_SCALE is not set
+# CONFIG_REGISTERS is not set
 
 #
 # CLPS711X/EP721X Implementations
 #
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
 # CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
 # CONFIG_ARCH_ACORN is not set
 # CONFIG_FOOTBRIDGE is not set
 # CONFIG_FOOTBRIDGE_HOST is not set
 # CONFIG_FOOTBRIDGE_ADDIN is not set
 CONFIG_CPU_32=y
 # CONFIG_CPU_26 is not set
-
-#
-# Processor Type
-#
 # CONFIG_CPU_32v3 is not set
 CONFIG_CPU_32v4=y
 # CONFIG_CPU_ARM610 is not set
 # CONFIG_CPU_ARM710 is not set
 # CONFIG_CPU_ARM720T is not set
 # CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_CPU_ARM926T is not set
 # CONFIG_CPU_ARM1020 is not set
 # CONFIG_CPU_SA110 is not set
 CONFIG_CPU_SA1100=y
+# CONFIG_ARM_THUMB is not set
 CONFIG_DISCONTIGMEM=y
 
 #
 # General setup
 #
-
-#
-# Please ensure that you have read the help on the next option
-#
-# CONFIG_ANGELBOOT is not set
 # CONFIG_PCI is not set
-# CONFIG_ISA is not set
+CONFIG_ISA=y
 # CONFIG_ISA_DMA is not set
+# CONFIG_CPU_FREQ is not set
 CONFIG_HOTPLUG=y
 
 #
 # PCMCIA/CardBus support
 #
 CONFIG_PCMCIA=y
+# CONFIG_I82092 is not set
 # CONFIG_I82365 is not set
 # CONFIG_TCIC is not set
 # CONFIG_PCMCIA_CLPS6700 is not set
 CONFIG_PCMCIA_SA1100=y
+# CONFIG_MERCURY_BACKPAQ is not set
 CONFIG_NET=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_FASTFPE is not set
+CONFIG_FPE_FASTFPE=y
 CONFIG_KCORE_ELF=y
 # CONFIG_KCORE_AOUT is not set
 CONFIG_BINFMT_AOUT=m
@@ -145,10 +159,8 @@
 # CONFIG_APM is not set
 # CONFIG_ARTHUR is not set
 CONFIG_CMDLINE="keepinitrd"
-# CONFIG_PFS168_CMDLINE is not set
 # CONFIG_LEDS is not set
-# CONFIG_ALIGNMENT_TRAP is not set
-# CONFIG_UCB1200 is not set
+CONFIG_ALIGNMENT_TRAP=y
 
 #
 # Parallel port support
@@ -159,63 +171,72 @@
 # 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
+CONFIG_MTD_DEBUG=y
+CONFIG_MTD_DEBUG_VERBOSE=1
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_BOOTLDR_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
 
 #
-# Linearly Mapped Flash Device Drivers
+# RAM/ROM/Flash chip drivers
 #
 CONFIG_MTD_CFI=y
-# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_CFI_B1 is not set
+CONFIG_MTD_CFI_B2=y
+CONFIG_MTD_CFI_B4=y
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
 CONFIG_MTD_CFI_INTELEXT=y
 # CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
 # CONFIG_MTD_AMDSTD is not set
 # CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
 # CONFIG_MTD_PHYSMAP is not set
 # 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_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
 CONFIG_MTD_SA1100=y
+# CONFIG_MTD_H3600_BACKPAQ is not set
 # CONFIG_MTD_DC21285 is not set
 # CONFIG_MTD_IQ80310 is not set
-# CONFIG_MTD_CSTM_CFI_JEDEC is not set
-# CONFIG_MTD_JEDEC is not set
-# CONFIG_MTD_MIXMEM is not set
-# CONFIG_MTD_OCTAGON is not set
-# CONFIG_MTD_VMAX is not set
 
 #
-# NAND Flash Device Drivers
+# Self-contained MTD device drivers
 #
-# CONFIG_MTD_NAND is not set
-# CONFIG_MTD_NAND_SPIA is not set
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
 
 #
-# User Modules And Translation Layers
+# NAND Flash Device Drivers
 #
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
+# CONFIG_MTD_NAND is not set
 
 #
 # Plug and Play configuration
@@ -246,6 +267,7 @@
 # CONFIG_MD_RAID0 is not set
 # CONFIG_MD_RAID1 is not set
 # CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_BLK_DEV_LVM is not set
 
 #
@@ -258,7 +280,7 @@
 # CONFIG_NETLINK_DEV is not set
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
-# CONFIG_FILTER is not set
+CONFIG_FILTER=y
 CONFIG_UNIX=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
@@ -282,10 +304,7 @@
 # CONFIG_IPV6 is not set
 # CONFIG_KHTTPD is not set
 # CONFIG_ATM is not set
-
-#
-#
-#
+# CONFIG_VLAN_8021Q is not set
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
 # CONFIG_DECNET is not set
@@ -318,7 +337,6 @@
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
 # CONFIG_ETHERTAP is not set
-# CONFIG_NET_SB1000 is not set
 
 #
 # Ethernet (10 or 100Mbit)
@@ -329,18 +347,44 @@
 # Ethernet (1000 Mbit)
 #
 # CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
-# CONFIG_PPP is not set
+# CONFIG_PLIP is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPPOE is not set
 # CONFIG_SLIP is not set
 
 #
 # Wireless LAN (non-hamradio)
 #
-# CONFIG_NET_RADIO is not set
+CONFIG_NET_RADIO=y
+# CONFIG_STRIP is not set
+CONFIG_WAVELAN=m
+CONFIG_ARLAN=m
+CONFIG_AIRONET4500=m
+CONFIG_AIRONET4500_NONCS=m
+# CONFIG_AIRONET4500_PNP is not set
+# CONFIG_AIRONET4500_PCI is not set
+# CONFIG_AIRONET4500_ISA is not set
+# CONFIG_AIRONET4500_I365 is not set
+# CONFIG_AIRONET4500_PROC is not set
+# CONFIG_AIRO is not set
+CONFIG_HERMES=m
+CONFIG_PCMCIA_HERMES=m
+CONFIG_AIRO_CS=m
+CONFIG_NET_WIRELESS=y
 
 #
 # Token Ring devices
@@ -366,11 +410,11 @@
 CONFIG_PCMCIA_NMCLAN=m
 CONFIG_PCMCIA_SMC91C92=m
 CONFIG_PCMCIA_XIRC2PS=m
+# CONFIG_PCMCIA_AXNET is not set
 # CONFIG_ARCNET_COM20020_CS is not set
 # CONFIG_PCMCIA_IBMTR is not set
 CONFIG_NET_PCMCIA_RADIO=y
 # CONFIG_PCMCIA_RAYCS is not set
-# CONFIG_PCMCIA_HERMES is not set
 # CONFIG_PCMCIA_NETWAVE is not set
 CONFIG_PCMCIA_WAVELAN=m
 CONFIG_AIRONET4500_CS=m
@@ -384,10 +428,6 @@
 # IrDA (infrared) support
 #
 CONFIG_IRDA=m
-
-#
-# IrDA protocols
-#
 CONFIG_IRLAN=m
 # CONFIG_IRNET is not set
 CONFIG_IRCOMM=m
@@ -397,28 +437,19 @@
 #
 # Infrared-port device drivers
 #
-
-#
-# SIR device drivers
-#
 # CONFIG_IRTTY_SIR is not set
 # CONFIG_IRPORT_SIR is not set
-
-#
-# FIR device drivers
-#
+# CONFIG_DONGLE is not set
+# CONFIG_USB_IRDA is not set
 # CONFIG_NSC_FIR is not set
 # CONFIG_WINBOND_FIR is not set
 # CONFIG_TOSHIBA_FIR is not set
 # CONFIG_SMC_IRCC_FIR is not set
+# CONFIG_ALI_FIR is not set
+# CONFIG_VLSI_FIR is not set
 CONFIG_SA1100_FIR=m
 
 #
-# Dongle support
-#
-# CONFIG_DONGLE is not set
-
-#
 # ATA/IDE/MFM/RLL support
 #
 CONFIG_IDE=m
@@ -427,10 +458,6 @@
 # IDE, ATA and ATAPI Block devices
 #
 CONFIG_BLK_DEV_IDE=m
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
 # CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_BLK_DEV_IDEDISK=m
@@ -445,14 +472,10 @@
 # CONFIG_BLK_DEV_COMMERIAL is not set
 # CONFIG_BLK_DEV_TIVO is not set
 CONFIG_BLK_DEV_IDECS=m
-# CONFIG_BLK_DEV_IDECD is not set
+CONFIG_BLK_DEV_IDECD=m
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_BLK_DEV_IDESCSI is not set
-
-#
-# IDE chipset support/bugfixes
-#
 # CONFIG_BLK_DEV_CMD640 is not set
 # CONFIG_BLK_DEV_CMD640_ENHANCED is not set
 # CONFIG_BLK_DEV_ISAPNP is not set
@@ -460,6 +483,9 @@
 # CONFIG_IDEDMA_AUTO is not set
 # CONFIG_DMA_NONPCI is not set
 # CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
 
 #
 # SCSI support
@@ -483,7 +509,13 @@
 #
 # Input core support
 #
-# CONFIG_INPUT is not set
+CONFIG_INPUT=y
+# CONFIG_INPUT_KEYBDEV is not set
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
 
 #
 # Character devices
@@ -493,19 +525,37 @@
 CONFIG_SERIAL=m
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
 CONFIG_SERIAL_SA1100=y
 CONFIG_SERIAL_SA1100_CONSOLE=y
 CONFIG_SA1100_DEFAULT_BAUDRATE=115200
-# CONFIG_TOUCHSCREEN_UCB1200 is not set
-# CONFIG_TOUCHSCREEN_BITSY is not set
-CONFIG_PROFILER=m
-# CONFIG_PFS168_SPI is not set
-# CONFIG_PFS168_DTMF is not set
-# CONFIG_PFS168_MISC is not set
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=32
+# CONFIG_NEWTONKBD is not set
 
 #
 # I2C support
@@ -513,6 +563,15 @@
 # CONFIG_I2C is not set
 
 #
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
 # Mice
 #
 # CONFIG_BUSMOUSE is not set
@@ -524,11 +583,33 @@
 #
 # Joysticks
 #
-# CONFIG_JOYSTICK is not set
-
-#
-# Input core support is needed for joysticks
-#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_NS558 is not set
+# CONFIG_INPUT_LIGHTNING is not set
+# CONFIG_INPUT_PCIGAME is not set
+# CONFIG_INPUT_CS461X is not set
+# CONFIG_INPUT_EMU10K1 is not set
+# CONFIG_INPUT_SERIO is not set
+# CONFIG_INPUT_SERPORT is not set
+# CONFIG_INPUT_ANALOG is not set
+# CONFIG_INPUT_A3D is not set
+# CONFIG_INPUT_ADI is not set
+# CONFIG_INPUT_COBRA is not set
+# CONFIG_INPUT_GF2K is not set
+# CONFIG_INPUT_GRIP is not set
+# CONFIG_INPUT_INTERACT is not set
+# CONFIG_INPUT_TMDC is not set
+# CONFIG_INPUT_SIDEWINDER is not set
+# CONFIG_INPUT_IFORCE_USB is not set
+# CONFIG_INPUT_IFORCE_232 is not set
+# CONFIG_INPUT_WARRIOR is not set
+# CONFIG_INPUT_MAGELLAN is not set
+# CONFIG_INPUT_SPACEORB is not set
+# CONFIG_INPUT_SPACEBALL is not set
+# CONFIG_INPUT_STINGER is not set
+# CONFIG_INPUT_DB9 is not set
+# CONFIG_INPUT_GAMECON is not set
+# CONFIG_INPUT_TURBOGRAFX is not set
 # CONFIG_QIC02_TAPE is not set
 
 #
@@ -553,12 +634,13 @@
 #
 # PCMCIA character devices
 #
-CONFIG_PCMCIA_SERIAL_CS=m
+# CONFIG_PCMCIA_SERIAL_CS is not set
 
 #
 # Multimedia devices
 #
 # CONFIG_VIDEO_DEV is not set
+# CONFIG_V4L2_DEV is not set
 
 #
 # File systems
@@ -568,37 +650,45 @@
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_BFS_FS is not set
-CONFIG_FAT_FS=m
-CONFIG_MSDOS_FS=m
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
 # CONFIG_UMSDOS_FS is not set
-CONFIG_VFAT_FS=m
+# CONFIG_VFAT_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
-# CONFIG_JFFS2_FS is not set
-CONFIG_CRAMFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=2
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
 CONFIG_RAMFS=y
-# CONFIG_ISO9660_FS is not set
+CONFIG_ISO9660_FS=m
 # CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
 # CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
 # CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
 CONFIG_PROC_FS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVFS_MOUNT is not set
-# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVFS_FS=y
+CONFIG_DEVFS_MOUNT=y
+CONFIG_DEVFS_DEBUG=y
+# CONFIG_DRIVERFS_FS is not set
 CONFIG_DEVPTS_FS=y
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_QNX4FS_RW is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_EXT2_FS=y
 # CONFIG_SYSV_FS is not set
-# CONFIG_SYSV_FS_WRITE is not set
 # CONFIG_UDF_FS is not set
 # CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
@@ -608,6 +698,7 @@
 # Network File Systems
 #
 # CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=m
 CONFIG_NFS_V3=y
 # CONFIG_ROOT_NFS is not set
@@ -616,8 +707,7 @@
 CONFIG_SUNRPC=m
 CONFIG_LOCKD=m
 CONFIG_LOCKD_V4=y
-CONFIG_SMB_FS=m
-# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_SMB_FS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_NCPFS_PACKET_SIGNING is not set
 # CONFIG_NCPFS_IOCTL_LOCKING is not set
@@ -627,59 +717,22 @@
 # CONFIG_NCPFS_SMALLDOS is not set
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
 
 #
 # Partition Types
 #
 # CONFIG_PARTITION_ADVANCED is not set
 CONFIG_MSDOS_PARTITION=y
-CONFIG_SMB_NLS=y
-CONFIG_NLS=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=y
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_ISO8859_1 is not set
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_UTF8 is not set
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
 
 #
 # Console drivers
 #
 CONFIG_PC_KEYMAP=y
 # CONFIG_VGA_CONSOLE is not set
-CONFIG_FB=y
 
 #
 # Frame-buffer support
@@ -687,16 +740,17 @@
 CONFIG_FB=y
 CONFIG_DUMMY_CONSOLE=y
 # CONFIG_FB_ACORN is not set
+# CONFIG_FB_ANAKIN is not set
 # CONFIG_FB_CLPS711X is not set
+# CONFIG_FB_SA1100 is not set
 CONFIG_FB_EPSON1356=y
 # CONFIG_FB_CYBER2000 is not set
-# CONFIG_FB_SA1100 is not set
 # CONFIG_FB_VIRTUAL is not set
 CONFIG_FBCON_ADVANCED=y
 # CONFIG_FBCON_MFB is not set
 # CONFIG_FBCON_CFB2 is not set
 # CONFIG_FBCON_CFB4 is not set
-CONFIG_FBCON_CFB8=y
+# CONFIG_FBCON_CFB8 is not set
 CONFIG_FBCON_CFB16=y
 # CONFIG_FBCON_CFB24 is not set
 # CONFIG_FBCON_CFB32 is not set
@@ -721,10 +775,10 @@
 # Sound
 #
 CONFIG_SOUND=m
-CONFIG_SOUND_UDA1341=m
-# CONFIG_SOUND_SA1100_SSP is not set
+# CONFIG_SOUND_BT878 is not set
 # CONFIG_SOUND_CMPCI is not set
 # CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_MIDI_EMU10K1 is not set
 # CONFIG_SOUND_FUSION is not set
 # CONFIG_SOUND_CS4281 is not set
 # CONFIG_SOUND_ES1370 is not set
@@ -733,28 +787,121 @@
 # CONFIG_SOUND_MAESTRO is not set
 # CONFIG_SOUND_MAESTRO3 is not set
 # CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_RME96XX is not set
 # CONFIG_SOUND_SONICVIBES is not set
 # CONFIG_SOUND_TRIDENT is not set
 # CONFIG_SOUND_MSNDCLAS is not set
 # CONFIG_SOUND_MSNDPIN is not set
 # CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_MIDI_VIA82CXXX is not set
+CONFIG_SOUND_SA1100=m
+# CONFIG_SOUND_UDA1341 is not set
+# CONFIG_SOUND_ASSABET_UDA1341 is not set
+# CONFIG_SOUND_H3600_UDA1341 is not set
+# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
+# CONFIG_SOUND_SA1111_UDA1341 is not set
+# CONFIG_SOUND_SA1100SSP is not set
 # CONFIG_SOUND_OSS is not set
+# CONFIG_SOUND_WAVEARTIST is not set
 # CONFIG_SOUND_TVMIXER is not set
 
 #
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
 # USB support
 #
 # CONFIG_USB is not set
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+# CONFIG_USB_OHCI_SA1111 is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_HID is not set
+# CONFIG_USB_HIDDEV is not set
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_RIO500 is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
 
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
-CONFIG_DEBUG_ERRORS=y
+CONFIG_FRAME_POINTER=y
 # CONFIG_DEBUG_USER is not set
 # CONFIG_DEBUG_INFO is not set
-# CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_NO_PGT_CACHE is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SLAB=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_LL=y
 # CONFIG_DEBUG_DC21285_PORT is not set
 # CONFIG_DEBUG_CLPS711X_UART2 is not set
+# CONFIG_DEBUG_LL_SER3 is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/def-configs/lart linux/arch/arm/def-configs/lart
--- linux.orig/arch/arm/def-configs/lart	Thu Oct 25 20:53:44 2001
+++ linux/arch/arm/def-configs/lart	Tue May 28 22:39:25 2002
@@ -892,7 +892,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/def-configs/neponset linux/arch/arm/def-configs/neponset
--- linux.orig/arch/arm/def-configs/neponset	Thu Oct 25 20:53:45 2001
+++ linux/arch/arm/def-configs/neponset	Tue May 28 22:39:22 2002
@@ -950,7 +950,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/def-configs/pangolin linux/arch/arm/def-configs/pangolin
--- linux.orig/arch/arm/def-configs/pangolin	Thu Oct 25 20:53:45 2001
+++ linux/arch/arm/def-configs/pangolin	Tue May 28 22:39:28 2002
@@ -741,7 +741,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_INFO=y
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/def-configs/pfs168_mqtft linux/arch/arm/def-configs/pfs168_mqtft
--- linux.orig/arch/arm/def-configs/pfs168_mqtft	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/def-configs/pfs168_mqtft	Tue May 28 22:39:28 2002
@@ -783,7 +783,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_INFO=y
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/def-configs/pfs168_mqvga linux/arch/arm/def-configs/pfs168_mqvga
--- linux.orig/arch/arm/def-configs/pfs168_mqvga	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/def-configs/pfs168_mqvga	Tue May 28 22:39:13 2002
@@ -783,7 +783,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_INFO=y
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/def-configs/pfs168_sastn linux/arch/arm/def-configs/pfs168_sastn
--- linux.orig/arch/arm/def-configs/pfs168_sastn	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/def-configs/pfs168_sastn	Tue May 28 22:39:15 2002
@@ -774,7 +774,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_INFO=y
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/def-configs/pfs168_satft linux/arch/arm/def-configs/pfs168_satft
--- linux.orig/arch/arm/def-configs/pfs168_satft	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/def-configs/pfs168_satft	Tue May 28 22:39:13 2002
@@ -783,7 +783,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_INFO=y
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/def-configs/pleb linux/arch/arm/def-configs/pleb
--- linux.orig/arch/arm/def-configs/pleb	Mon Aug 13 00:36:24 2001
+++ linux/arch/arm/def-configs/pleb	Tue May 28 22:39:18 2002
@@ -524,7 +524,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/def-configs/rpc linux/arch/arm/def-configs/rpc
--- linux.orig/arch/arm/def-configs/rpc	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/def-configs/rpc	Tue May 28 22:39:12 2002
@@ -839,7 +839,7 @@
 #
 # Kernel hacking
 #
-# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/def-configs/shannon linux/arch/arm/def-configs/shannon
--- linux.orig/arch/arm/def-configs/shannon	Thu Jan  1 00:00:00 1970
+++ linux/arch/arm/def-configs/shannon	Tue May 28 22:39:13 2002
@@ -0,0 +1,737 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_OBSOLETE=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_RPC is not set
+CONFIG_ARCH_SA1100=y
+# CONFIG_ARCH_SHARK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
+
+#
+# Footbridge Implementations
+#
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+CONFIG_SA1100_SHANNON=y
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_USB is not set
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+
+#
+# Processor Type
+#
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_SA110 is not set
+CONFIG_CPU_SA1100=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_DISCONTIGMEM=y
+
+#
+# General setup
+#
+# CONFIG_PCI is not set
+CONFIG_ISA=y
+# CONFIG_ISA_DMA is not set
+# CONFIG_CPU_FREQ is not set
+CONFIG_HOTPLUG=y
+
+#
+# PCMCIA/CardBus support
+#
+CONFIG_PCMCIA=y
+# CONFIG_I82092 is not set
+# CONFIG_I82365 is not set
+# CONFIG_TCIC is not set
+CONFIG_PCMCIA_SA1100=y
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="console=ttySA0,9600 console=tty1 root=/dev/mtdblock2 init=/linuxrc"
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_BOOTLDR_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+CONFIG_MTD_SA1100=y
+# CONFIG_MTD_IQ80310 is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD 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
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+# CONFIG_NETLINK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+# CONFIG_PCMCIA_3C589 is not set
+# CONFIG_PCMCIA_3C574 is not set
+# CONFIG_PCMCIA_FMVJ18X is not set
+CONFIG_PCMCIA_PCNET=y
+# CONFIG_PCMCIA_NMCLAN is not set
+CONFIG_PCMCIA_SMC91C92=y
+# CONFIG_PCMCIA_XIRC2PS is not set
+# CONFIG_NET_PCMCIA_RADIO is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+CONFIG_IDE=m
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=m
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_BLK_DEV_IDEDISK is not set
+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
+# CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_DMA_NONPCI is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_ATARAID is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_KEYBDEV=y
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_SA1100=y
+CONFIG_SERIAL_SA1100_CONSOLE=y
+CONFIG_SA1100_DEFAULT_BAUDRATE=9600
+# CONFIG_SERIAL_8250 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+
+#
+# Other L3 adapters
+#
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_SERIO is not set
+
+#
+# Joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_WDT is not set
+# CONFIG_WDTPCI is not set
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_ADVANTECH_WDT is not set
+CONFIG_SA1100_WATCHDOG=y
+# CONFIG_EUROTECH_WDT is not set
+# CONFIG_IB700_WDT is not set
+# CONFIG_I810_TCO is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_60XX_WDT is not set
+# CONFIG_W83877F_WDT is not set
+# CONFIG_MACHZ_WDT is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+CONFIG_SA1100_RTC=y
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_CMS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+# CONFIG_UMSDOS_FS is not set
+CONFIG_VFAT_FS=y
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+CONFIG_MINIX_FS=y
+# CONFIG_FREEVXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_EXT2_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFSD is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Console drivers
+#
+CONFIG_PC_KEYMAP=y
+# CONFIG_VGA_CONSOLE is not set
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FB_SA1100=y
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_CFB2=y
+CONFIG_FBCON_CFB4=y
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
+# CONFIG_FBCON_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+CONFIG_SOUND_SA1100=y
+# CONFIG_SOUND_SA1100SSP is not set
+# CONFIG_SOUND_OSS is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+CONFIG_MCP=y
+CONFIG_MCP_SA1100=y
+CONFIG_MCP_UCB1200=y
+CONFIG_MCP_UCB1200_AUDIO=y
+CONFIG_MCP_UCB1200_TS=y
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
+
+#
+# USB Device Class drivers
+#
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+# USB Imaging devices
+#
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network adaptors
+#
+
+#
+# USB port drivers
+#
+
+#
+# USB Serial Converter support
+#
+
+#
+# USB Miscellaneous drivers
+#
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_LL=y
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/def-configs/shark linux/arch/arm/def-configs/shark
--- linux.orig/arch/arm/def-configs/shark	Thu Oct 25 20:53:45 2001
+++ linux/arch/arm/def-configs/shark	Tue May 28 22:39:16 2002
@@ -956,7 +956,7 @@
 #
 # Kernel hacking
 #
-CONFIG_NO_FRAME_POINTER=y
+CONFIG_FRAME_POINTER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/def-configs/system3 linux/arch/arm/def-configs/system3
--- linux.orig/arch/arm/def-configs/system3	Thu Jan  1 00:00:00 1970
+++ linux/arch/arm/def-configs/system3	Tue May 28 22:39:14 2002
@@ -0,0 +1,977 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_RPC is not set
+CONFIG_ARCH_SA1100=y
+# CONFIG_ARCH_SHARK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+CONFIG_SA1100_PT_SYSTEM3=y
+CONFIG_SA1111=y
+CONFIG_FORCE_MAX_ZONEORDER=9
+CONFIG_SA1100_USB=m
+CONFIG_SA1100_USB_NETLINK=m
+CONFIG_SA1100_USB_CHAR=m
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+
+#
+# Processor Type
+#
+# CONFIG_CPU_32v3 is not set
+CONFIG_CPU_32v4=y
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_SA110 is not set
+CONFIG_CPU_SA1100=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_DISCONTIGMEM=y
+
+#
+# General setup
+#
+# CONFIG_PCI is not set
+CONFIG_ISA=y
+# CONFIG_ISA_DMA is not set
+CONFIG_CPU_FREQ=y
+CONFIG_HOTPLUG=y
+
+#
+# PCMCIA/CardBus support
+#
+CONFIG_PCMCIA=m
+# CONFIG_I82092 is not set
+# CONFIG_I82365 is not set
+# CONFIG_TCIC is not set
+# CONFIG_PCMCIA_CLPS6700 is not set
+CONFIG_PCMCIA_SA1100=m
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# At least one math emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_PM=y
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="noinitrd root=/dev/mtdblock3"
+CONFIG_LEDS=y
+CONFIG_LEDS_TIMER=y
+CONFIG_LEDS_CPU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=m
+CONFIG_MTD_BOOTLDR_PARTS=m
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+# CONFIG_MTD_CHAR is not set
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+CONFIG_MTD_SA1100=y
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD 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
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+CONFIG_DUMMY=m
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+CONFIG_NET_VENDOR_SMC=y
+# CONFIG_WD80x3 is not set
+# CONFIG_ULTRAMCA is not set
+# CONFIG_ULTRA is not set
+# CONFIG_ULTRA32 is not set
+CONFIG_SMC9194=m
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+# CONFIG_PCMCIA_3C589 is not set
+# CONFIG_PCMCIA_3C574 is not set
+# CONFIG_PCMCIA_FMVJ18X is not set
+CONFIG_PCMCIA_PCNET=m
+# CONFIG_PCMCIA_NMCLAN is not set
+CONFIG_PCMCIA_SMC91C92=m
+# CONFIG_PCMCIA_XIRC2PS is not set
+# CONFIG_PCMCIA_AXNET is not set
+# CONFIG_ARCNET_COM20020_CS is not set
+# CONFIG_PCMCIA_IBMTR is not set
+# CONFIG_NET_PCMCIA_RADIO is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+# CONFIG_IRNET is not set
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+# CONFIG_IRDA_OPTIONS is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+CONFIG_IRPORT_SIR=m
+
+#
+# Dongle support
+#
+# CONFIG_DONGLE is not set
+
+#
+# FIR device drivers
+#
+# CONFIG_USB_IRDA is not set
+# CONFIG_NSC_FIR is not set
+# CONFIG_WINBOND_FIR is not set
+# CONFIG_TOSHIBA_FIR is not set
+# CONFIG_SMC_IRCC_FIR is not set
+# CONFIG_ALI_FIR is not set
+# CONFIG_VLSI_FIR is not set
+CONFIG_SA1100_FIR=m
+
+#
+# ATA/IDE/MFM/RLL support
+#
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
+# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
+# CONFIG_BLK_DEV_IDEDISK_IBM is not set
+# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
+# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
+# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
+# CONFIG_BLK_DEV_IDEDISK_WD is not set
+# CONFIG_BLK_DEV_COMMERIAL is not set
+# CONFIG_BLK_DEV_TIVO is not set
+CONFIG_BLK_DEV_IDECS=m
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_DMA_NONPCI is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_KEYBDEV=y
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+# CONFIG_VT_CONSOLE is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+CONFIG_SERIAL_SA1100=y
+CONFIG_SERIAL_SA1100_CONSOLE=y
+CONFIG_SA1100_DEFAULT_BAUDRATE=38400
+CONFIG_SERIAL_8250=m
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=32
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_NS558 is not set
+# CONFIG_INPUT_LIGHTNING is not set
+# CONFIG_INPUT_PCIGAME is not set
+# CONFIG_INPUT_CS461X is not set
+# CONFIG_INPUT_EMU10K1 is not set
+# CONFIG_INPUT_SERIO is not set
+# CONFIG_INPUT_SERPORT is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_ANALOG is not set
+# CONFIG_INPUT_A3D is not set
+# CONFIG_INPUT_ADI is not set
+# CONFIG_INPUT_COBRA is not set
+# CONFIG_INPUT_GF2K is not set
+# CONFIG_INPUT_GRIP is not set
+# CONFIG_INPUT_INTERACT is not set
+# CONFIG_INPUT_TMDC is not set
+# CONFIG_INPUT_SIDEWINDER is not set
+# CONFIG_INPUT_IFORCE_USB is not set
+# CONFIG_INPUT_IFORCE_232 is not set
+# CONFIG_INPUT_WARRIOR is not set
+# CONFIG_INPUT_MAGELLAN is not set
+# CONFIG_INPUT_SPACEORB is not set
+# CONFIG_INPUT_SPACEBALL is not set
+# CONFIG_INPUT_STINGER is not set
+# CONFIG_INPUT_DB9 is not set
+# CONFIG_INPUT_GAMECON is not set
+# CONFIG_INPUT_TURBOGRAFX is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_SA1100_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+CONFIG_PCMCIA_SERIAL_CS=m
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+# CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_ROOT_NFS is not set
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Console drivers
+#
+CONFIG_PC_KEYMAP=y
+# CONFIG_VGA_CONSOLE is not set
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_ACORN is not set
+# CONFIG_FB_ANAKIN is not set
+# CONFIG_FB_CLPS711X is not set
+CONFIG_FB_SA1100=y
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_CFB2=y
+CONFIG_FBCON_CFB4=y
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+CONFIG_FBCON_FONTWIDTH8_ONLY=y
+CONFIG_FBCON_FONTS=y
+CONFIG_FONT_8x8=y
+# CONFIG_FONT_8x16 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+
+#
+# USB support
+#
+CONFIG_USB=m
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_LONG_TIMEOUT is not set
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+CONFIG_USB_OHCI_SA1111=m
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_ACM is not set
+CONFIG_USB_PRINTER=m
+
+#
+# USB Human Interface Devices (HID)
+#
+CONFIG_USB_HID=m
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_KBD=m
+CONFIG_USB_MOUSE=m
+# CONFIG_USB_WACOM is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+
+#
+#   Video4Linux support is needed for USB Multimedia device support
+#
+
+#
+# USB Network adaptors
+#
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+CONFIG_USB_USBNET=m
+
+#
+# USB port drivers
+#
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_RIO500 is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_NO_PGT_CACHE is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SLAB=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_WAITQ=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/kernel/Makefile linux/arch/arm/kernel/Makefile
--- linux.orig/arch/arm/kernel/Makefile	Thu Oct 25 20:53:45 2001
+++ linux/arch/arm/kernel/Makefile	Tue May 28 22:39:30 2002
@@ -42,7 +42,8 @@
 
 no-irq-arch	:= $(CONFIG_ARCH_INTEGRATOR) $(CONFIG_ARCH_CLPS711X) \
 		   $(CONFIG_FOOTBRIDGE) $(CONFIG_ARCH_EBSA110) \
-		   $(CONFIG_ARCH_SA1100) $(CONFIG_ARCH_CAMELOT)
+		   $(CONFIG_ARCH_SA1100) $(CONFIG_ARCH_CAMELOT) \
+		   $(CONFIG_ARCH_MX1ADS)
 
 ifneq ($(findstring y,$(no-irq-arch)),y)
   obj-y		+= irq-arch.o
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/kernel/armksyms.c linux/arch/arm/kernel/armksyms.c
--- linux.orig/arch/arm/kernel/armksyms.c	Thu Oct 11 16:04:57 2001
+++ linux/arch/arm/kernel/armksyms.c	Tue May 28 22:39:23 2002
@@ -77,12 +77,12 @@
 extern void __do_softirq(void);
 
 #define EXPORT_SYMBOL_ALIAS(sym,orig)		\
- const char __kstrtab_##sym##[]			\
+ const char __kstrtab_##sym[]			\
   __attribute__((section(".kstrtab"))) =	\
     __MODULE_STRING(sym);			\
  const struct module_symbol __ksymtab_##sym	\
   __attribute__((section("__ksymtab"))) =	\
-    { (unsigned long)&##orig, __kstrtab_##sym };
+    { (unsigned long)&orig, __kstrtab_##sym };
 
 /*
  * floating point math emulator support.
@@ -115,7 +115,9 @@
 EXPORT_SYMBOL(system_rev);
 EXPORT_SYMBOL(system_serial_low);
 EXPORT_SYMBOL(system_serial_high);
+#ifdef CONFIG_DEBUG_BUGVERBOSE
 EXPORT_SYMBOL(__bug);
+#endif
 EXPORT_SYMBOL(__bad_xchg);
 EXPORT_SYMBOL(__readwrite_bug);
 EXPORT_SYMBOL(enable_irq);
@@ -229,6 +231,7 @@
 EXPORT_SYMBOL_NOVERS(__udivmoddi4);
 EXPORT_SYMBOL_NOVERS(__udivsi3);
 EXPORT_SYMBOL_NOVERS(__umodsi3);
+EXPORT_SYMBOL_NOVERS(abort);
 
 	/* bitops */
 EXPORT_SYMBOL(set_bit);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/kernel/bios32.c linux/arch/arm/kernel/bios32.c
--- linux.orig/arch/arm/kernel/bios32.c	Thu Oct 11 16:04:57 2001
+++ linux/arch/arm/kernel/bios32.c	Tue May 28 22:39:24 2002
@@ -153,8 +153,7 @@
 }
 
 /*
- * PCI IDE controllers use non-standard I/O port
- * decoding, respect it.
+ * PCI IDE controllers use non-standard I/O port decoding, respect it.
  */
 static void __init pci_fixup_ide_bases(struct pci_dev *dev)
 {
@@ -181,9 +180,82 @@
 	pci_write_config_dword(dev, 0x40, 0x80000000);
 }
 
+/*
+ * The CY82C693 needs some rather major fixups to ensure that it does
+ * the right thing.  Idea from the Alpha people, with a few additions.
+ *
+ * We ensure that the IDE base registers are set to 1f0/3f4 for the
+ * primary bus, and 170/374 for the secondary bus.  Also, hide them
+ * from the PCI subsystem view as well so we won't try to perform
+ * our own auto-configuration on them.
+ *
+ * In addition, we ensure that the PCI IDE interrupts are routed to
+ * IRQ 14 and IRQ 15 respectively.
+ *
+ * The above gets us to a point where the IDE on this device is
+ * functional.  However, The CY82C693U _does not work_ in bus
+ * master mode without locking the PCI bus solid.
+ */
+static void __init pci_fixup_cy82c693(struct pci_dev *dev)
+{
+	if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
+		u32 base0, base1;
+
+		if (dev->class & 0x80) {	/* primary */
+			base0 = 0x1f0;
+			base1 = 0x3f4;
+		} else {			/* secondary */
+			base0 = 0x170;
+			base1 = 0x374;
+		}
+
+		pci_write_config_dword(dev, PCI_BASE_ADDRESS_0,
+				       base0 | PCI_BASE_ADDRESS_SPACE_IO);
+		pci_write_config_dword(dev, PCI_BASE_ADDRESS_1,
+				       base1 | PCI_BASE_ADDRESS_SPACE_IO);
+
+		dev->resource[0].start = 0;
+		dev->resource[0].end   = 0;
+		dev->resource[0].flags = 0;
+
+		dev->resource[1].start = 0;
+		dev->resource[1].end   = 0;
+		dev->resource[1].flags = 0;
+	} else if (PCI_FUNC(dev->devfn) == 0) {
+		/*
+		 * Setup IDE IRQ routing.
+		 */
+		pci_write_config_byte(dev, 0x4b, 14);
+		pci_write_config_byte(dev, 0x4c, 15);
+
+		/*
+		 * Disable FREQACK handshake, enable USB.
+		 */
+		pci_write_config_byte(dev, 0x4d, 0x41);
+
+		/*
+		 * Enable PCI retry, and PCI post-write buffer.
+		 */
+		pci_write_config_byte(dev, 0x44, 0x17);
+
+		/*
+		 * Enable ISA master and DMA post write buffering.
+		 */
+		pci_write_config_byte(dev, 0x45, 0x03);
+	}
+}
+
 struct pci_fixup pcibios_fixups[] = {
 	{
 		PCI_FIXUP_HEADER,
+		PCI_VENDOR_ID_CONTAQ,	PCI_DEVICE_ID_CONTAQ_82C693,
+		pci_fixup_cy82c693
+	}, {
+		PCI_FIXUP_HEADER,
+		PCI_VENDOR_ID_DEC,	PCI_DEVICE_ID_DEC_21142,
+		pci_fixup_dec21142
+	}, {
+		PCI_FIXUP_HEADER,
 		PCI_VENDOR_ID_DEC,	PCI_DEVICE_ID_DEC_21285,
 		pci_fixup_dec21285
 	}, {
@@ -198,10 +270,6 @@
 		PCI_FIXUP_HEADER,
 		PCI_ANY_ID,		PCI_ANY_ID,
 		pci_fixup_ide_bases
-	}, {
-		PCI_FIXUP_HEADER,
-		PCI_VENDOR_ID_DEC,	PCI_DEVICE_ID_DEC_21142,
-		pci_fixup_dec21142
 	}, { 0 }
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/kernel/calls.S linux/arch/arm/kernel/calls.S
--- linux.orig/arch/arm/kernel/calls.S	Mon Oct  8 17:39:18 2001
+++ linux/arch/arm/kernel/calls.S	Tue May 28 22:39:28 2002
@@ -236,6 +236,27 @@
 		.long	SYMBOL_NAME(sys_mincore)
 /* 220 */	.long	SYMBOL_NAME(sys_madvise)
 		.long	SYMBOL_NAME(sys_fcntl64)
+		.long	SYMBOL_NAME(sys_ni_syscall) /* TUX */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* Security */
+		.long	SYMBOL_NAME(sys_gettid)
+/* 225 */	.long	SYMBOL_NAME(sys_readahead)
+		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_setxattr */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_lsetxattr */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_fsetxattr */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_getxattr */
+/* 230 */	.long	SYMBOL_NAME(sys_ni_syscall) /* sys_lgetxattr */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_fgetxattr */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_listxattr */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_llistxattr */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_flistxattr */
+/* 235 */	.long	SYMBOL_NAME(sys_ni_syscall) /* sys_removexattr */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_lremovexattr */
+		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_fremovexattr */
+		.long	SYMBOL_NAME(sys_tkill)
+		/*
+		 * Please check 2.5 _before_ adding calls here,
+		 * and copy changes to rmk@arm.linux.org.uk.  Thanks.
+		 */
 __syscall_end:
 
 		.rept	NR_syscalls - (__syscall_end - __syscall_start) / 4
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/kernel/compat.c linux/arch/arm/kernel/compat.c
--- linux.orig/arch/arm/kernel/compat.c	Thu Oct 11 16:04:57 2001
+++ linux/arch/arm/kernel/compat.c	Tue May 28 22:39:14 2002
@@ -89,10 +89,12 @@
 	}
 
 #ifdef CONFIG_FOOTBRIDGE
-	tag = tag_next(tag);
-	tag->hdr.tag = ATAG_MEMCLK;
-	tag->hdr.size = tag_size(tag_memclk);
-	tag->u.memclk.fmemclk = params->u1.s.mem_fclk_21285;
+	if (params->u1.s.mem_fclk_21285) {
+		tag = tag_next(tag);
+		tag->hdr.tag = ATAG_MEMCLK;
+		tag->hdr.size = tag_size(tag_memclk);
+		tag->u.memclk.fmemclk = params->u1.s.mem_fclk_21285;
+	}
 #endif
 
 #ifdef CONFIG_ARCH_ACORN
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/kernel/debug-armv.S linux/arch/arm/kernel/debug-armv.S
--- linux.orig/arch/arm/kernel/debug-armv.S	Thu Oct 25 20:53:45 2001
+++ linux/arch/arm/kernel/debug-armv.S	Tue May 28 22:39:23 2002
@@ -164,28 +164,49 @@
 		.endm
 
 #elif defined(CONFIG_ARCH_SA1100)
+
 		.macro	addruart,rx
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1			@ MMU enabled?
 		moveq	\rx, #0x80000000	@ physical base address
 		movne	\rx, #0xf8000000	@ virtual address
-		@add	\rx, \rx, #0x00050000	@ Ser3
-		add	\rx, \rx, #0x00010000	@ Ser1
+
+		@ We probe for the active serial port here, coherently with
+		@ the comment in include/asm-arm/arch-sa1100/uncompress.h.
+		@ We assume r1 can be clobbered.
+
+		@ see if Ser3 is active
+		add	\rx, \rx, #0x00050000
+		ldr	r1, [\rx, #UTCR3]
+		tst	r1, #UTCR3_TXE
+
+		@ if Ser3 is inactive, then try Ser1
+		addeq	\rx, \rx, #(0x00010000 - 0x00050000)
+		ldreq	r1, [\rx, #UTCR3]
+		tsteq	r1, #UTCR3_TXE
+
+		@ if Ser1 is inactive, then try Ser2
+		addeq	\rx, \rx, #(0x00030000 - 0x00010000)
+		ldreq	r1, [\rx, #UTCR3]
+		tsteq	r1, #UTCR3_TXE
+
+		@ if all ports are inactive, then there is nothing we can do
+		moveq	pc, lr
 		.endm
 
 		.macro	senduart,rd,rx
-		str	\rd, [\rx, #0x14]	@ UTDR
+		str	\rd, [\rx, #UTDR]
 		.endm
 
 		.macro	waituart,rd,rx
-1001:		ldr	\rd, [\rx, #0x20]	@ UTSR1
-		tst	\rd, #1 << 2		@ UTSR1_TNF
+1001:		ldr	\rd, [\rx, #UTSR1]
+		tst	\rd, #UTSR1_TNF
 		beq	1001b
 		.endm
 
 		.macro	busyuart,rd,rx
-1001:		ldr	\rd, [\rx, #0x20]	@ UTSR1
-		tst	\rd, #1 << 0		@ UTSR1_TBY
+1001:		ldr	\rd, [\rx, #UTSR1]
+		tst	\rd, #UTSR1_TBY
 		bne	1001b
 		.endm
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/kernel/dma-arc.c linux/arch/arm/kernel/dma-arc.c
--- linux.orig/arch/arm/kernel/dma-arc.c	Wed Jul  4 21:56:44 2001
+++ linux/arch/arm/kernel/dma-arc.c	Tue May 28 22:39:30 2002
@@ -96,7 +96,7 @@
 	/* 10/1/1999 DAG - Presume whether there is an outstanding command? */
 	extern unsigned int fdc1772_fdc_int_done;
 
-	* Explicit! If the int done is 0 then 1 int to go */
+	/* Explicit! If the int done is 0 then 1 int to go */
 	return (fdc1772_fdc_int_done==0)?1:0;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/kernel/dma.c linux/arch/arm/kernel/dma.c
--- linux.orig/arch/arm/kernel/dma.c	Fri Feb  9 19:29:44 2001
+++ linux/arch/arm/kernel/dma.c	Tue May 28 22:39:30 2002
@@ -275,6 +275,8 @@
 
 #endif
 
+EXPORT_SYMBOL(request_dma);
+EXPORT_SYMBOL(free_dma);
 EXPORT_SYMBOL(enable_dma);
 EXPORT_SYMBOL(disable_dma);
 EXPORT_SYMBOL(set_dma_addr);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/kernel/entry-armv.S linux/arch/arm/kernel/entry-armv.S
--- linux.orig/arch/arm/kernel/entry-armv.S	Thu Oct 25 20:53:45 2001
+++ linux/arch/arm/kernel/entry-armv.S	Tue May 28 22:39:22 2002
@@ -454,6 +454,31 @@
 		.macro	irq_prio_table
 		.endm
 
+#elif defined(CONFIG_ARCH_MX1ADS)
+
+		.macro	disable_fiq
+		.endm
+#define AITC_NIVECSR   0x40
+		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+		ldr	\irqstat, =IO_ADDRESS(MX1ADS_AITC_BASE)
+		@ Load offset & priority of the highest priority
+		@ interrupt pending.
+		ldr	\irqnr, [\irqstat, #AITC_NIVECSR]
+		@ Shift off the priority leaving the offset or
+		@ "interrupt number"
+		mov	\irqnr, \irqnr, lsr #16
+ 		ldr	\irqstat, =1	@ dummy compare
+		ldr	\base, =0xFFFF		// invalid interrupt
+		cmp	\irqnr, \base
+		bne	1001f
+		ldr	\irqstat, =0
+1001:
+		tst	\irqstat, #1	@ to make the condition code = TRUE
+		.endm
+
+		.macro	irq_prio_table
+		.endm
+
 #elif defined(CONFIG_ARCH_CLPS711X)
 
 #include <asm/hardware/clps7111.h>
@@ -643,14 +668,14 @@
 		mrs	r9, cpsr			@ Enable interrupts if they were
 		tst	r3, #I_BIT
 		biceq	r9, r9, #I_BIT			@ previously
-		mov	r0, r2
+		mov	r0, r2				@ *** remove once everyones in sync
 /*
  * This routine must not corrupt r9
  */
 #ifdef MULTI_CPU
-		ldr	r2, .LCprocfns			@ pass r0, r3 to
+		ldr	r4, .LCprocfns			@ pass r0, r3 to
 		mov	lr, pc				@ processor code
-		ldr	pc, [r2]			@ call processor specific code
+		ldr	pc, [r4]			@ call processor specific code
 #else
 		bl	cpu_data_abort
 #endif
@@ -747,15 +772,16 @@
 		stmia	sp, {r0 - r12}			@ save r0 - r12
 		ldr	r7, .LCabt
 		add	r5, sp, #S_PC
-		ldmia	r7, {r0, r3, r4}		@ Get USR pc, cpsr
-		stmia	r5, {r0, r3, r4}		@ Save USR pc, cpsr, old_r0
+		ldmia	r7, {r2 - r4}			@ Get USR pc, cpsr
+		stmia	r5, {r2 - r4}			@ Save USR pc, cpsr, old_r0
 		stmdb	r5, {sp, lr}^
 		alignment_trap r7, r7, __temp_abt
 		zero_fp
+		mov	r0, r2				@ remove once everyones in sync
 #ifdef MULTI_CPU
-		ldr	r2, .LCprocfns			@ pass r0, r3 to
+		ldr	r4, .LCprocfns			@ pass r0, r3 to
 		mov	lr, pc				@ processor code
-		ldr	pc, [r2]			@ call processor specific code
+		ldr	pc, [r4]			@ call processor specific code
 #else
 		bl	cpu_data_abort
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/kernel/entry-header.S linux/arch/arm/kernel/entry-header.S
--- linux.orig/arch/arm/kernel/entry-header.S	Thu Oct 11 16:04:57 2001
+++ linux/arch/arm/kernel/entry-header.S	Tue May 28 22:39:25 2002
@@ -13,7 +13,7 @@
 #endif
 
 		.macro	zero_fp
-#ifndef CONFIG_NO_FRAME_POINTER
+#ifdef CONFIG_FRAME_POINTER
 		mov	fp, #0
 #endif
 		.endm
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/kernel/init_task.c linux/arch/arm/kernel/init_task.c
--- linux.orig/arch/arm/kernel/init_task.c	Thu Oct 11 16:04:57 2001
+++ linux/arch/arm/kernel/init_task.c	Tue May 28 22:39:24 2002
@@ -9,7 +9,6 @@
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 
-static struct vm_area_struct init_mmap = INIT_MMAP;
 static struct fs_struct init_fs = INIT_FS;
 static struct files_struct init_files = INIT_FILES;
 static struct signal_struct init_signals = INIT_SIGNALS;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/kernel/process.c linux/arch/arm/kernel/process.c
--- linux.orig/arch/arm/kernel/process.c	Sun Sep 30 19:26:08 2001
+++ linux/arch/arm/kernel/process.c	Tue May 28 22:39:23 2002
@@ -24,9 +24,8 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 
-#include <asm/system.h>
-#include <asm/io.h>
 #include <asm/leds.h>
+#include <asm/system.h>
 #include <asm/uaccess.h>
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/kernel/semaphore.c linux/arch/arm/kernel/semaphore.c
--- linux.orig/arch/arm/kernel/semaphore.c	Mon Feb 25 19:37:52 2002
+++ linux/arch/arm/kernel/semaphore.c	Tue May 28 22:39:25 2002
@@ -210,7 +210,6 @@
 	mov	r0, ip
 	bl	__up
 	ldmfd	sp!, {r0 - r3, pc}^
-
 	");
 
 #else
@@ -248,7 +247,6 @@
 	mov	r0, ip
 	bl	__up
 	ldmfd	sp!, {r0 - r3, pc}
-
 	");
 
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/kernel/signal.c linux/arch/arm/kernel/signal.c
--- linux.orig/arch/arm/kernel/signal.c	Thu Oct 11 16:04:57 2001
+++ linux/arch/arm/kernel/signal.c	Tue May 28 22:39:13 2002
@@ -344,7 +344,7 @@
 	/*
 	 * This is the X/Open sanctioned signal stack switching.
 	 */
-	if ((ka->sa.sa_flags & SA_ONSTACK) && sas_ss_flags(sp))
+	if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp))
 		sp = current->sas_ss_sp + current->sas_ss_size;
 
 	/*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/kernel/traps.c linux/arch/arm/kernel/traps.c
--- linux.orig/arch/arm/kernel/traps.c	Thu Oct 11 16:04:57 2001
+++ linux/arch/arm/kernel/traps.c	Tue May 28 22:39:25 2002
@@ -25,8 +25,6 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 
-#include <asm/atomic.h>
-#include <asm/io.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -53,7 +51,7 @@
  */
 static int verify_stack(unsigned long sp)
 {
-	if (sp < PAGE_OFFSET || sp > (unsigned long)high_memory)
+	if (sp < PAGE_OFFSET || (sp > (unsigned long)high_memory && high_memory != 0))
 		return -EFAULT;
 
 	return 0;
@@ -62,13 +60,15 @@
 /*
  * Dump out the contents of some memory nicely...
  */
-void dump_mem(unsigned long bottom, unsigned long top)
+static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
 {
 	unsigned long p = bottom & ~31;
 	int i;
 
+	printk("%s(0x%08lx to 0x%08lx)\n", str, bottom, top);
+
 	for (p = bottom & ~31; p < top;) {
-		printk("%08lx: ", p);
+		printk("%04lx: ", p & 0xffff);
 
 		for (i = 0; i < 8; i++, p += 4) {
 			unsigned int val;
@@ -79,21 +79,11 @@
 				__get_user(val, (unsigned long *)p);
 				printk("%08x ", val);
 			}
-			if (i == 3)
-				printk(" ");
 		}
 		printk ("\n");
 	}
 }
 
-/*
- * These constants are for searching for possible module text
- * segments.  VMALLOC_OFFSET comes from mm/vmalloc.c; MODULE_RANGE is
- * a guess of how much space is likely to be vmalloced.
- */
-#define VMALLOC_OFFSET (8*1024*1024)
-#define MODULE_RANGE (8*1024*1024)
-
 static void dump_instr(struct pt_regs *regs)
 {
 	unsigned long addr = instruction_pointer(regs);
@@ -102,7 +92,7 @@
 	int i;
 
 	printk("Code: ");
-	for (i = -2; i < 3; i++) {
+	for (i = -4; i < 1; i++) {
 		unsigned int val, bad;
 
 		if (thumb)
@@ -122,8 +112,7 @@
 
 static void dump_stack(struct task_struct *tsk, unsigned long sp)
 {
-	printk("Stack:\n");
-	dump_mem(sp - 16, 8192+(unsigned long)tsk);
+	dump_mem("Stack: ", sp - 16, 8192+(unsigned long)tsk);
 }
 
 static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
@@ -289,10 +278,9 @@
 		handler[reason], processor_modes[proc_mode]);
 
 	/*
-	 * We need to switch to kernel mode so that we can
-	 * use __get_user to safely read from kernel space.
-	 * Note that we now dump the code first, just in case
-	 * the backtrace kills us.
+	 * We need to switch to kernel mode so that we can use __get_user
+	 * to safely read from kernel space.  Note that we now dump the
+	 * code first, just in case the backtrace kills us.
 	 */
 	fs = get_fs();
 	set_fs(KERNEL_DS);
@@ -301,10 +289,8 @@
 	 * Dump out the vectors and stub routines.  Maybe a better solution
 	 * would be to dump them out only if we detect that they are corrupted.
 	 */
-	printk(KERN_CRIT "Vectors:\n");
-	dump_mem(vectors, 0x40);
-	printk(KERN_CRIT "Stubs:\n");
-	dump_mem(vectors + 0x200, 0x4b8);
+	dump_mem(KERN_CRIT "Vectors: ", vectors, vectors + 0x40);
+	dump_mem(KERN_CRIT "Stubs: ", vectors + 0x200, vectors + 0x4b8);
 
 	set_fs(fs);
 
@@ -528,11 +514,6 @@
 
 void abort(void)
 {
-	void *lr = __builtin_return_address(0);
-
-	printk(KERN_CRIT "abort() called from %p!  (Please "
-	       "report to rmk@arm.linux.org.uk)\n", lr);
-
 	BUG();
 
 	/* if that doesn't kill us, halt */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/kernel/via82c505.c linux/arch/arm/kernel/via82c505.c
--- linux.orig/arch/arm/kernel/via82c505.c	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/kernel/via82c505.c	Tue May 28 22:39:13 2002
@@ -157,8 +157,15 @@
 	struct pci_bus *bus;
 
 	printk(KERN_DEBUG "PCI: VIA 82c505\n");
-	request_region(0xA8,2,"via config");
-	request_region(0xCF8,8,"pci config");
+	if (!request_region(0xA8,2,"via config")) {
+		printk(KERN_WARNING"VIA 82c505: Unable to request region 0xA8\n");
+		return;
+	}
+	if (!request_region(0xCF8,8,"pci config")) {
+		printk(KERN_WARNING"VIA 82c505: Unable to request region 0xCF8\n");
+		release_region(0xA8, 2);
+		return;
+	}
 
 	/* Enable compatible Mode */
 	outb(0x96,0xA8);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/lib/backtrace.S linux/arch/arm/lib/backtrace.S
--- linux.orig/arch/arm/lib/backtrace.S	Thu Oct 25 20:53:45 2001
+++ linux/arch/arm/lib/backtrace.S	Tue May 28 22:39:18 2002
@@ -26,7 +26,7 @@
 
 ENTRY(c_backtrace)
 
-#ifdef CONFIG_NO_FRAME_POINTER
+#ifndef CONFIG_FRAME_POINTER
 		mov	pc, lr
 #else
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/lib/ecard.S linux/arch/arm/lib/ecard.S
--- linux.orig/arch/arm/lib/ecard.S	Tue Nov 28 01:07:59 2000
+++ linux/arch/arm/lib/ecard.S	Tue May 28 22:39:22 2002
@@ -12,7 +12,7 @@
 #include <asm/assembler.h>
 #include <asm/hardware.h>
 
-#if defined(CONFIG_CPU_26)
+#ifdef CONFIG_CPU_26
 #define CPSR2SPSR(rt)
 #else
 #define CPSR2SPSR(rt) \
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/lib/getuser.S linux/arch/arm/lib/getuser.S
--- linux.orig/arch/arm/lib/getuser.S	Thu Oct 11 16:04:57 2001
+++ linux/arch/arm/lib/getuser.S	Tue May 28 22:39:28 2002
@@ -80,8 +80,9 @@
 
 	/* fall through */
 
-__get_user_bad:
+__get_user_bad_8:
 	mov	r2, #0
+__get_user_bad:
 	mov	r1, #0
 	mov	r0, #-14
 	mov	pc, lr
@@ -91,6 +92,6 @@
 	.long	2b, __get_user_bad
 	.long	3b, __get_user_bad
 	.long	4b, __get_user_bad
-	.long	5b, __get_user_bad
-	.long	6b, __get_user_bad
+	.long	5b, __get_user_bad_8
+	.long	6b, __get_user_bad_8
 .previous
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/lib/io-acorn.S linux/arch/arm/lib/io-acorn.S
--- linux.orig/arch/arm/lib/io-acorn.S	Thu Oct 25 20:53:45 2001
+++ linux/arch/arm/lib/io-acorn.S	Tue May 28 22:39:18 2002
@@ -58,7 +58,7 @@
 @ Proto  : void memc_write(int register, int value);
 @ Returns: nothing
 
-#if defined(CONFIG_CPU_26)
+#ifdef CONFIG_CPU_26
 ENTRY(memc_write)
 		cmp	r0, #7
 		RETINSTR(movgt,pc,lr)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/lib/io-shark.c linux/arch/arm/lib/io-shark.c
--- linux.orig/arch/arm/lib/io-shark.c	Thu Apr 12 19:20:31 2001
+++ linux/arch/arm/lib/io-shark.c	Tue May 28 22:39:18 2002
@@ -1,7 +1,7 @@
 /*
  *  linux/arch/arm/lib/io-shark.c
  *
- *  by Alexander Schulz <aschulz@netwinder.org>
+ *  by Alexander Schulz
  *
  * derived from:
  * linux/arch/arm/lib/io-ebsa.S
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/lib/strrchr.S linux/arch/arm/lib/strrchr.S
--- linux.orig/arch/arm/lib/strrchr.S	Mon Sep 18 22:15:25 2000
+++ linux/arch/arm/lib/strrchr.S	Tue May 28 22:39:28 2002
@@ -18,7 +18,7 @@
 		mov	r3, #0
 1:		ldrb	r2, [r0], #1
 		teq	r2, r1
-		moveq	r3, r0
+		subeq	r3, r0, #1
 		teq	r2, #0
 		bne	1b
 		mov	r0, r3
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-clps711x/Makefile linux/arch/arm/mach-clps711x/Makefile
--- linux.orig/arch/arm/mach-clps711x/Makefile	Thu Jan  1 00:00:00 1970
+++ linux/arch/arm/mach-clps711x/Makefile	Tue May 28 22:39:18 2002
@@ -0,0 +1,30 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET		:= clps711x.o
+
+# Object file lists.
+
+obj-y			:= irq.o mm.o time.o
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+export-objs		:= leds-p720t.o
+
+obj-$(CONFIG_ARCH_AUTCPU12) += autcpu12.o
+obj-$(CONFIG_ARCH_CDB89712) += cdb89712.o
+obj-$(CONFIG_ARCH_CLEP7312) += clep7312.o
+obj-$(CONFIG_ARCH_EDB7211) += edb7211-arch.o edb7211-mm.o
+obj-$(CONFIG_ARCH_P720T) += p720t.o
+obj-$(CONFIG_ARCH_FORTUNET) += fortunet.o
+leds-$(CONFIG_ARCH_P720T) += p720t-leds.o
+obj-$(CONFIG_LEDS)	+= $(leds-y)
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-clps711x/autcpu12.c linux/arch/arm/mach-clps711x/autcpu12.c
--- linux.orig/arch/arm/mach-clps711x/autcpu12.c	Thu Jan  1 00:00:00 1970
+++ linux/arch/arm/mach-clps711x/autcpu12.c	Tue May 28 22:39:24 2002
@@ -0,0 +1,72 @@
+/*
+ *  linux/arch/arm/mach-clps711x/autcpu12.c
+ *
+ * (c) 2001 Thomas Gleixner, autronix automation <gleixner@autronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/blk.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/hardware.h>
+#include <asm/sizes.h>
+#include <asm/io.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+
+#include <asm/mach/map.h>
+#include <asm/arch/autcpu12.h>
+
+extern void clps711x_map_io(void);
+extern void clps711x_init_irq(void);
+
+/*
+ * The on-chip registers are given a size of 1MB so that a section can
+ * be used to map them; this saves a page table.  This is the place to
+ * add mappings for ROM, expansion memory, PCMCIA, etc.  (if static
+ * mappings are chosen for those areas).
+ *
+*/
+
+static struct map_desc autcpu12_io_desc[] __initdata = {
+ /* virtual, physical, length, domain, r, w, c, b */
+ /* memory-mapped extra io and CS8900A Ethernet chip */
+ /* ethernet chip */
+ 	{ AUTCPU12_VIRT_CS8900A, AUTCPU12_PHYS_CS8900A, SZ_1M, DOMAIN_IO, 1, 1, 0, 0 },
+	
+ 	LAST_DESC
+};
+
+void __init autcpu12_map_io(void)
+{
+        clps711x_map_io();
+        iotable_init(autcpu12_io_desc);
+}
+
+MACHINE_START(AUTCPU12, "autronix autcpu12")
+	MAINTAINER("Thomas Gleixner")
+        BOOT_MEM(0xc0000000, 0x80000000, 0xff000000)
+	BOOT_PARAMS(0xc0020000)
+	MAPIO(autcpu12_map_io)
+	INITIRQ(clps711x_init_irq)
+MACHINE_END
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-clps711x/cdb89712.c linux/arch/arm/mach-clps711x/cdb89712.c
--- linux.orig/arch/arm/mach-clps711x/cdb89712.c	Thu Jan  1 00:00:00 1970
+++ linux/arch/arm/mach-clps711x/cdb89712.c	Tue May 28 22:39:12 2002
@@ -0,0 +1,74 @@
+/*
+ *  linux/arch/arm/mach-clps711x/cdb89712.c
+ *
+ *  Copyright (C) 2000-2001 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+extern void clps711x_init_irq(void);
+extern void clps711x_map_io(void);
+
+/*
+ * Map the CS89712 Ethernet port.  That should be moved to the
+ * ethernet driver, perhaps.
+ */
+static struct map_desc cdb89712_io_desc[] __initdata = {
+	{ ETHER_BASE, ETHER_START, ETHER_SIZE, DOMAIN_IO, 0, 1, 0, 0 },
+	LAST_DESC
+};
+
+static void __init
+fixup_cdb89712(struct machine_desc *desc, struct param_struct *params,
+	    char **cmdline, struct meminfo *mi)
+{
+}
+
+static void __init cdb89712_map_io(void)
+{
+	clps711x_map_io();
+	iotable_init(cdb89712_io_desc);
+}
+
+MACHINE_START(CDB89712, "Cirrus-CDB89712")
+	MAINTAINER("Ray Lehtiniemi")
+	BOOT_MEM(0xc0000000, 0x80000000, 0xff000000)
+	BOOT_PARAMS(0xc0000100)
+	FIXUP(fixup_cdb89712)
+	MAPIO(cdb89712_map_io)
+	INITIRQ(clps711x_init_irq)
+MACHINE_END
+
+static int cdb89712_hw_init(void)
+{
+	return 0;
+}
+
+__initcall(cdb89712_hw_init);
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-clps711x/clep7312.c linux/arch/arm/mach-clps711x/clep7312.c
--- linux.orig/arch/arm/mach-clps711x/clep7312.c	Thu Jan  1 00:00:00 1970
+++ linux/arch/arm/mach-clps711x/clep7312.c	Tue May 28 22:39:29 2002
@@ -0,0 +1,49 @@
+/*
+ *  linux/arch/arm/mach-clps711x/clep7312.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/string.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+extern void clps711x_init_irq(void);
+extern void clps711x_map_io(void); 
+
+static void __init
+fixup_clep7312(struct machine_desc *desc, struct param_struct *params,
+	    char **cmdline, struct meminfo *mi)
+{
+	mi->nr_banks=1;
+	mi->end = 0xc0FFFFFF;
+	mi->bank[0].start = 0xc0000000;
+	mi->bank[0].size = 0x01000000;
+	mi->bank[0].node = 0;
+}
+
+
+MACHINE_START(CLEP7212, "Cirrus Logic 7212/7312")
+	MAINTAINER("Nobody")
+        BOOT_MEM(0xc0000000, 0x80000000, 0xff000000)
+	BOOT_PARAMS(0xc0000100)
+	FIXUP(fixup_clep7312)
+	MAPIO(clps711x_map_io)
+	INITIRQ(clps711x_init_irq)
+MACHINE_END
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-clps711x/dma.c linux/arch/arm/mach-clps711x/dma.c
--- linux.orig/arch/arm/mach-clps711x/dma.c	Thu Jan  1 00:00:00 1970
+++ linux/arch/arm/mach-clps711x/dma.c	Tue May 28 22:39:16 2002
@@ -0,0 +1,35 @@
+/*
+ *  linux/arch/arm/mach-clps711x/dma.c
+ *
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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
+ */
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/mman.h>
+#include <linux/init.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+
+#include <asm/mach/dma.h>
+
+void __init arch_dma_init(dma_t *dma)
+{
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-clps711x/edb7211-arch.c linux/arch/arm/mach-clps711x/edb7211-arch.c
--- linux.orig/arch/arm/mach-clps711x/edb7211-arch.c	Thu Jan  1 00:00:00 1970
+++ linux/arch/arm/mach-clps711x/edb7211-arch.c	Tue May 28 22:39:23 2002
@@ -0,0 +1,59 @@
+/*
+ *  linux/arch/arm/mach-clps711x/arch-edb7211.c
+ *
+ *  Copyright (C) 2000, 2001 Blue Mug, Inc.  All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/string.h>
+
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+extern void clps711x_init_irq(void);
+extern void edb7211_map_io(void);
+
+static void __init
+fixup_edb7211(struct machine_desc *desc, struct param_struct *params,
+	      char **cmdline, struct meminfo *mi)
+{
+	/*
+	 * Bank start addresses are not present in the information
+	 * passed in from the boot loader.  We could potentially
+	 * detect them, but instead we hard-code them.
+	 *
+	 * Banks sizes _are_ present in the param block, but we're
+	 * not using that information yet.
+	 */
+	mi->bank[0].start = 0xc0000000;
+	mi->bank[0].size = 8*1024*1024;
+	mi->bank[0].node = 0;
+	mi->bank[1].start = 0xc1000000;
+	mi->bank[1].size = 8*1024*1024;
+	mi->bank[1].node = 1;
+	mi->nr_banks = 2;
+}
+
+MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)")
+	MAINTAINER("Jon McClintock")
+	BOOT_MEM(0xc0000000, 0x80000000, 0xff000000)
+	BOOT_PARAMS(0xc0020100)	/* 0xc0000000 - 0xc001ffff can be video RAM */
+	FIXUP(fixup_edb7211)
+	MAPIO(edb7211_map_io)
+	INITIRQ(clps711x_init_irq)
+MACHINE_END
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-clps711x/edb7211-mm.c linux/arch/arm/mach-clps711x/edb7211-mm.c
--- linux.orig/arch/arm/mach-clps711x/edb7211-mm.c	Thu Jan  1 00:00:00 1970
+++ linux/arch/arm/mach-clps711x/edb7211-mm.c	Tue May 28 22:39:26 2002
@@ -0,0 +1,74 @@
+/*
+ *  linux/arch/arm/mach-clps711x/mm.c
+ *
+ *  Extra MM routines for the EDB7211 board
+ *
+ *  Copyright (C) 2000, 2001 Blue Mug, Inc.  All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+ 
+#include <asm/mach/map.h>
+
+#define MB1 1048576	/* one megabyte == size of an MMU section */
+
+extern void clps711x_map_io(void);
+
+/*
+ * The on-chip registers are given a size of 1MB so that a section can
+ * be used to map them; this saves a page table.  This is the place to
+ * add mappings for ROM, expansion memory, PCMCIA, etc.  (if static
+ * mappings are chosen for those areas).
+ *
+ * Here is a physical memory map (to be fleshed out later):
+ *
+ * Physical Address  Size  Description
+ * ----------------- ----- ---------------------------------
+ * c0000000-c001ffff 128KB reserved for video RAM [1]
+ * c0020000-c0023fff  16KB parameters (see Documentation/arm/Setup)
+ * c0024000-c0027fff  16KB swapper_pg_dir (task 0 page directory)
+ * c0028000-...            kernel image (TEXTADDR)
+ *
+ * [1] Unused pages should be given back to the VM; they are not yet.
+ *     The parameter block should also be released (not sure if this
+ *     happens).
+ */
+static struct map_desc edb7211_io_desc[] __initdata = {
+ /* virtual, physical, length, domain, r, w, c, b */
+
+ /* memory-mapped extra keyboard row and CS8900A Ethernet chip */
+ { EP7211_VIRT_EXTKBD, EP7211_PHYS_EXTKBD, MB1, DOMAIN_IO, 1, 1, 0, 0 }, 
+ { EP7211_VIRT_CS8900A, EP7211_PHYS_CS8900A, MB1, DOMAIN_IO, 1, 1, 0, 0 },
+
+ /* flash banks */
+ { EP7211_VIRT_FLASH1, EP7211_PHYS_FLASH1, MB1 * 8, DOMAIN_KERNEL, 1, 1, 0, 0 },
+ { EP7211_VIRT_FLASH2, EP7211_PHYS_FLASH2, MB1 * 8, DOMAIN_KERNEL, 1, 1, 0, 0 },
+
+ LAST_DESC
+};
+
+void __init edb7211_map_io(void)
+{
+        clps711x_map_io();
+        iotable_init(edb7211_io_desc);
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-clps711x/fortunet.c linux/arch/arm/mach-clps711x/fortunet.c
--- linux.orig/arch/arm/mach-clps711x/fortunet.c	Thu Jan  1 00:00:00 1970
+++ linux/arch/arm/mach-clps711x/fortunet.c	Tue May 28 22:39:17 2002
@@ -0,0 +1,81 @@
+/*
+ *  linux/arch/arm/mach-clps711x/fortunet.c
+ *
+ *  Derived from linux/arch/arm/mach-integrator/arch.c
+ *
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/blk.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/amba_kmi.h>
+
+extern void clps711x_map_io(void);
+extern void clps711x_init_irq(void);
+
+struct meminfo memmap = { 1, 0xC1000000, {{0xC0000000,0x01000000,0}}};
+
+typedef struct tag_IMAGE_PARAMS
+{
+	int	ramdisk_ok;
+	int	ramdisk_address;
+	int	ramdisk_size;
+	int	ram_size;
+	int	extra_param_type;
+	int	extra_param_ptr;
+	int	command_line;
+} IMAGE_PARAMS;
+
+#define IMAGE_PARAMS_PHYS	0xC01F0000
+
+static void __init
+fortunet_fixup(struct machine_desc *desc, struct param_struct *params,
+		 char **cmdline, struct meminfo *mi)
+{
+	IMAGE_PARAMS *ip;
+	ip = (IMAGE_PARAMS *)__phys_to_virt(IMAGE_PARAMS_PHYS);
+	*cmdline = (char *)__phys_to_virt(ip->command_line);
+#ifdef CONFIG_BLK_DEV_INITRD
+	if(ip->ramdisk_ok)
+	{
+		initrd_start = __phys_to_virt(ip->ramdisk_address);
+		initrd_end = initrd_start + ip->ramdisk_size;
+	}
+#endif
+	memmap.bank[0].size = ip->ram_size;
+	memmap.end = ip->ram_size+0xC0000000;
+	*mi = memmap;
+}
+
+MACHINE_START(FORTUNET, "ARM-FortuNet")
+	MAINTAINER("FortuNet Inc.")
+        BOOT_MEM(0xc0000000, 0x80000000, 0xf0000000)
+	BOOT_PARAMS(0x00000000)
+	FIXUP(fortunet_fixup)
+	MAPIO(clps711x_map_io)
+	INITIRQ(clps711x_init_irq)
+MACHINE_END
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-clps711x/irq.c linux/arch/arm/mach-clps711x/irq.c
--- linux.orig/arch/arm/mach-clps711x/irq.c	Thu Jan  1 00:00:00 1970
+++ linux/arch/arm/mach-clps711x/irq.c	Tue May 28 22:39:15 2002
@@ -0,0 +1,138 @@
+/*
+ *  linux/arch/arm/mach-clps711x/irq.c
+ *
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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
+ */
+#include <linux/init.h>
+
+#include <asm/mach/irq.h>
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include <asm/hardware/clps7111.h>
+
+static void mask_irq_int1(unsigned int irq)
+{
+	u32 intmr1;
+
+	intmr1 = clps_readl(INTMR1);
+	intmr1 &= ~(1 << irq);
+	clps_writel(intmr1, INTMR1);
+}
+
+static void mask_ack_irq_int1(unsigned int irq)
+{
+	u32 intmr1;
+
+	intmr1 = clps_readl(INTMR1);
+	intmr1 &= ~(1 << irq);
+	clps_writel(intmr1, INTMR1);
+
+	switch (irq) {
+	case IRQ_CSINT:  clps_writel(0, COEOI);  break;
+	case IRQ_TC1OI:  clps_writel(0, TC1EOI); break;
+	case IRQ_TC2OI:  clps_writel(0, TC2EOI); break;
+	case IRQ_RTCMI:  clps_writel(0, RTCEOI); break;
+	case IRQ_TINT:   clps_writel(0, TEOI);   break;
+	case IRQ_UMSINT: clps_writel(0, UMSEOI); break;
+	}
+}
+
+static void unmask_irq_int1(unsigned int irq)
+{
+	u32 intmr1;
+
+	intmr1 = clps_readl(INTMR1);
+	intmr1 |= 1 << irq;
+	clps_writel(intmr1, INTMR1);
+}
+
+static void mask_irq_int2(unsigned int irq)
+{
+	u32 intmr2;
+
+	intmr2 = clps_readl(INTMR2);
+	intmr2 &= ~(1 << (irq - 16));
+	clps_writel(intmr2, INTMR2);
+}
+
+static void mask_ack_irq_int2(unsigned int irq)
+{
+	u32 intmr2;
+
+	intmr2 = clps_readl(INTMR2);
+	intmr2 &= ~(1 << (irq - 16));
+	clps_writel(intmr2, INTMR2);
+
+	switch (irq) {
+	case IRQ_KBDINT: clps_writel(0, KBDEOI); break;
+	}
+}
+
+static void unmask_irq_int2(unsigned int irq)
+{
+	u32 intmr2;
+
+	intmr2 = clps_readl(INTMR2);
+	intmr2 |= 1 << (irq - 16);
+	clps_writel(intmr2, INTMR2);
+}
+
+void __init clps711x_init_irq(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < NR_IRQS; i++) {
+	        if (INT1_IRQS & (1 << i)) {
+		        irq_desc[i].valid	= 1;
+			irq_desc[i].probe_ok	= 1;
+			irq_desc[i].mask_ack	= (INT1_ACK_IRQS & (1 << i)) ?
+						   mask_ack_irq_int1 :
+						   mask_irq_int1;
+			irq_desc[i].mask	= mask_irq_int1;
+			irq_desc[i].unmask	= unmask_irq_int1;
+		}
+		if (INT2_IRQS & (1 << i)) {
+		        irq_desc[i].valid	= 1;
+			irq_desc[i].probe_ok	= 1;
+			irq_desc[i].mask_ack	= (INT2_ACK_IRQS & (1 << i)) ?
+						   mask_ack_irq_int2 :
+						   mask_irq_int2;
+			irq_desc[i].mask	= mask_irq_int2;
+			irq_desc[i].unmask	= unmask_irq_int2;
+		}			
+	}
+
+	/*
+	 * Disable interrupts
+	 */
+	clps_writel(0, INTMR1);
+	clps_writel(0, INTMR2);
+
+	/*
+	 * Clear down any pending interrupts
+	 */
+	clps_writel(0, COEOI);
+	clps_writel(0, TC1EOI);
+	clps_writel(0, TC2EOI);
+	clps_writel(0, RTCEOI);
+	clps_writel(0, TEOI);
+	clps_writel(0, UMSEOI);
+	clps_writel(0, SYNCIO);
+	clps_writel(0, KBDEOI);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-clps711x/mm.c linux/arch/arm/mach-clps711x/mm.c
--- linux.orig/arch/arm/mach-clps711x/mm.c	Thu Jan  1 00:00:00 1970
+++ linux/arch/arm/mach-clps711x/mm.c	Tue May 28 22:39:17 2002
@@ -0,0 +1,70 @@
+/*
+ *  linux/arch/arm/mach-clps711x/mm.c
+ *
+ *  Generic MM setup for the CLPS711x-based machines.
+ *
+ *  Copyright (C) 2001 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/bootmem.h>
+
+#include <asm/hardware.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/mach/map.h>
+#include <asm/hardware/clps7111.h>
+
+#if 0 //def CONFIG_DISCONTIGMEM
+  
+/*
+ * The assumption of maximum 4 discontiguous memory banks is present
+ * in several places in the ARM kernel, including the parameter block
+ * (this affects boot loaders, too).  Banks do not necessarily
+ * correspond 1:1 with NUMA nodes, although they usually will,
+ * especially if they are widely discontiguous.
+ *
+ *  - note that the parameter block is depreciated for new implementations
+ *  - also note that discontig_node_data is actually used
+ *    -- rmk 
+ */
+
+static bootmem_data_t node_bootmem_data[4];
+
+pg_data_t clps711x_node_data[4] = {
+        { bdata: &node_bootmem_data[0] },
+        { bdata: &node_bootmem_data[1] },
+        { bdata: &node_bootmem_data[2] },
+        { bdata: &node_bootmem_data[3] },
+};
+
+#endif
+
+/*
+ * This maps the generic CLPS711x registers
+ */
+static struct map_desc clps711x_io_desc[] __initdata = {
+ { CLPS7111_VIRT_BASE,	CLPS7111_PHYS_BASE,	1048576, DOMAIN_IO, 0, 1 },
+ LAST_DESC
+};
+
+void __init clps711x_map_io(void)
+{
+	iotable_init(clps711x_io_desc);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-clps711x/p720t-leds.c linux/arch/arm/mach-clps711x/p720t-leds.c
--- linux.orig/arch/arm/mach-clps711x/p720t-leds.c	Thu Jan  1 00:00:00 1970
+++ linux/arch/arm/mach-clps711x/p720t-leds.c	Tue May 28 22:39:29 2002
@@ -0,0 +1,67 @@
+/*
+ *  linux/arch/arm/mach-clps711x/leds.c
+ *
+ *  Integrator LED control routines
+ *
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+#include <asm/mach-types.h>
+
+#include <asm/hardware/clps7111.h>
+#include <asm/hardware/ep7212.h>
+
+static void p720t_leds_event(led_event_t ledevt)
+{
+	unsigned long flags;
+	u32 pddr;
+
+	local_irq_save(flags);
+	switch(ledevt) {
+	case led_idle_start:
+		break;
+
+	case led_idle_end:
+		break;
+
+	case led_timer:
+		pddr = clps_readb(PDDR);
+		clps_writeb(pddr ^ 1, PDDR);
+		break;
+
+	default:
+		break;
+	}
+
+	local_irq_restore(flags);
+}
+
+static int __init leds_init(void)
+{
+	if (machine_is_p720t())
+		leds_event = p720t_leds_event;
+
+	return 0;
+}
+
+__initcall(leds_init);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-clps711x/p720t.c linux/arch/arm/mach-clps711x/p720t.c
--- linux.orig/arch/arm/mach-clps711x/p720t.c	Thu Jan  1 00:00:00 1970
+++ linux/arch/arm/mach-clps711x/p720t.c	Tue May 28 22:39:24 2002
@@ -0,0 +1,118 @@
+/*
+ *  linux/arch/arm/mach-clps711x/p720t.c
+ *
+ *  Copyright (C) 2000-2001 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/arch/syspld.h>
+
+extern void clps711x_init_irq(void);
+extern void clps711x_map_io(void);
+
+/*
+ * Map the P720T system PLD.  It occupies two address spaces:
+ *  SYSPLD_PHYS_BASE and SYSPLD_PHYS_BASE + 0x00400000
+ * We map both here.
+ */
+static struct map_desc p720t_io_desc[] __initdata = {
+	{ SYSPLD_VIRT_BASE,	SYSPLD_PHYS_BASE, 1048576, DOMAIN_IO, 0, 1 },
+	{ 0xfe400000,		0x10400000,	  1048576, DOMAIN_IO, 0, 1 },
+	LAST_DESC
+};
+
+static void __init
+fixup_p720t(struct machine_desc *desc, struct param_struct *params,
+	    char **cmdline, struct meminfo *mi)
+{
+	struct tag *tag = (struct tag *)params;
+
+	/*
+	 * Our bootloader doesn't setup any tags (yet).
+	 */
+	if (tag->hdr.tag != ATAG_CORE) {
+		tag->hdr.tag = ATAG_CORE;
+		tag->hdr.size = tag_size(tag_core);
+		tag->u.core.flags = 0;
+		tag->u.core.pagesize = PAGE_SIZE;
+		tag->u.core.rootdev = 0x0100;
+
+		tag = tag_next(tag);
+		tag->hdr.tag = ATAG_MEM;
+		tag->hdr.size = tag_size(tag_mem32);
+		tag->u.mem.size = 4096;
+		tag->u.mem.start = PHYS_OFFSET;
+
+		tag = tag_next(tag);
+		tag->hdr.tag = ATAG_NONE;
+		tag->hdr.size = 0;
+	}
+}
+
+static void __init p720t_map_io(void)
+{
+	clps711x_map_io();
+	iotable_init(p720t_io_desc);
+}
+
+MACHINE_START(P720T, "ARM-Prospector720T")
+	MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
+	BOOT_MEM(0xc0000000, 0x80000000, 0xff000000)
+	BOOT_PARAMS(0xc0000100)
+	FIXUP(fixup_p720t)
+	MAPIO(p720t_map_io)
+	INITIRQ(clps711x_init_irq)
+MACHINE_END
+
+static int p720t_hw_init(void)
+{
+	/*
+	 * Power down as much as possible in case we don't
+	 * have the drivers loaded.
+	 */
+	PLD_LCDEN = 0;
+	PLD_PWR  &= ~(PLD_S4_ON|PLD_S3_ON|PLD_S2_ON|PLD_S1_ON);
+
+	PLD_KBD   = 0;
+	PLD_IO    = 0;
+	PLD_IRDA  = 0;
+	PLD_CODEC = 0;
+	PLD_TCH   = 0;
+	PLD_SPI   = 0;
+#ifndef CONFIG_DEBUG_LL
+	PLD_COM2  = 0;
+	PLD_COM1  = 0;
+#endif
+
+	return 0;
+}
+
+__initcall(p720t_hw_init);
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-clps711x/time.c linux/arch/arm/mach-clps711x/time.c
--- linux.orig/arch/arm/mach-clps711x/time.c	Thu Jan  1 00:00:00 1970
+++ linux/arch/arm/mach-clps711x/time.c	Tue May 28 22:39:13 2002
@@ -0,0 +1,54 @@
+/*
+ *  linux/arch/arm/mach-clps711x/time.c
+ *
+ *  Copyright (C) 2001 Deep Blue Solutions Ltd.
+ *
+ * This program is free software; you can redistribute 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 that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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
+ */
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/hardware/clps7111.h>
+
+extern unsigned long (*gettimeoffset)(void);
+
+/*
+ * gettimeoffset() returns time since last timer tick, in usecs.
+ *
+ * 'LATCH' is hwclock ticks (see CLOCK_TICK_RATE in timex.h) per jiffy.
+ * 'tick' is usecs per jiffy.
+ */
+static unsigned long clps711x_gettimeoffset(void)
+{
+	unsigned long hwticks;
+	hwticks = LATCH - (clps_readl(TC2D) & 0xffff);	/* since last underflow */
+	return (hwticks * tick) / LATCH;
+}
+
+void __init clps711x_setup_timer(void)
+{
+	unsigned int syscon;
+
+	gettimeoffset = clps711x_gettimeoffset;
+
+	syscon = clps_readl(SYSCON1);
+	syscon |= SYSCON1_TC2S | SYSCON1_TC2M;
+	clps_writel(syscon, SYSCON1);
+
+	clps_writel(LATCH-1, TC2D); /* 512kHz / 100Hz - 1 */
+
+	xtime.tv_sec = clps_readl(RTCDR);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-ebsa110/io.c linux/arch/arm/mach-ebsa110/io.c
--- linux.orig/arch/arm/mach-ebsa110/io.c	Thu Oct 11 16:04:57 2001
+++ linux/arch/arm/mach-ebsa110/io.c	Tue May 28 22:39:23 2002
@@ -139,7 +139,11 @@
 	 ((p) >> 3) == (0x2f8 >> 3) || \
 	 ((p) >> 3) == (0x378 >> 3))
 
-u8 __inb(int port)
+/*
+ * We're addressing an 8 or 16-bit peripheral which tranfers
+ * odd addresses on the low ISA byte lane.
+ */
+u8 __inb8(unsigned int port)
 {
 	u32 ret;
 
@@ -162,7 +166,11 @@
 	return ret;
 }
 
-u16 __inw(int port)
+/*
+ * We're addressing a 16-bit peripheral which transfers odd
+ * addresses on the high ISA byte lane.
+ */
+u8 __inb16(unsigned int port)
 {
 	u32 ret;
 
@@ -170,13 +178,33 @@
 	 * The SuperIO registers use sane addressing techniques...
 	 */
 	if (SUPERIO_PORT(port))
-		ret = __arch_getw(ISAIO_BASE + (port << 2));
+		ret = __arch_getb(ISAIO_BASE + (port << 2));
 	else {
 		u32 a = ISAIO_BASE + ((port & ~1) << 1);
 
 		/*
 		 * Shame nothing else does
 		 */
+		ret = __arch_getb(a + (port & 1));
+	}
+	return ret;
+}
+
+u16 __inw(unsigned int port)
+{
+	u32 ret;
+
+	/*
+	 * The SuperIO registers use sane addressing techniques...
+	 */
+	if (SUPERIO_PORT(port) || port & 1)
+		ret = __arch_getw(ISAIO_BASE + (port << 2));
+	else {
+		u32 a = ISAIO_BASE + (port << 1);
+
+		/*
+		 * Shame nothing else does
+		 */
 		if (port & 1)
 			BUG();
 
@@ -185,17 +213,27 @@
 	return ret;
 }
 
-u32 __inl(int port)
+/*
+ * Fake a 32-bit read with two 16-bit reads.  Needed for 3c589.
+ */
+u32 __inl(unsigned int port)
 {
-	BUG();
-	return 0;
+	u32 a;
+
+	if (SUPERIO_PORT(port) || port & 3)
+		BUG();
+
+	a = ISAIO_BASE + (port << 1);
+
+	return __arch_getw(a) | __arch_getw(a + 4) << 16;
 }
 
-EXPORT_SYMBOL(__inb);
+EXPORT_SYMBOL(__inb8);
+EXPORT_SYMBOL(__inb16);
 EXPORT_SYMBOL(__inw);
 EXPORT_SYMBOL(__inl);
 
-void __outb(u8 val, int port)
+void __outb8(u8 val, unsigned int port)
 {
 	/*
 	 * The SuperIO registers use sane addressing techniques...
@@ -215,7 +253,24 @@
 	}
 }
 
-void __outw(u16 val, int port)
+void __outb16(u8 val, unsigned int port)
+{
+	/*
+	 * The SuperIO registers use sane addressing techniques...
+	 */
+	if (SUPERIO_PORT(port))
+		__arch_putb(val, ISAIO_BASE + (port << 2));
+	else {
+		u32 a = ISAIO_BASE + ((port & ~1) << 1);
+
+		/*
+		 * Shame nothing else does
+		 */
+		__arch_putb(val, a + (port & 1));
+	}
+}
+
+void __outw(u16 val, unsigned int port)
 {
 	u32 off;
 
@@ -225,7 +280,7 @@
 	if (SUPERIO_PORT(port))
 		off = port << 2;
 	else {
-		off = (port & ~1) << 1;
+		off = port << 1;
 		if (port & 1)
 			BUG();
 
@@ -233,12 +288,13 @@
 	__arch_putw(val, ISAIO_BASE + off);
 }
 
-void __outl(u32 val, int port)
+void __outl(u32 val, unsigned int port)
 {
 	BUG();
 }
 
-EXPORT_SYMBOL(__outb);
+EXPORT_SYMBOL(__outb8);
+EXPORT_SYMBOL(__outb16);
 EXPORT_SYMBOL(__outw);
 EXPORT_SYMBOL(__outl);
 
@@ -315,12 +371,29 @@
 EXPORT_SYMBOL(outsw);
 EXPORT_SYMBOL(insw);
 
+/*
+ * We implement these as 16-bit insw/outsw, mainly for
+ * 3c589 cards.
+ */
 void outsl(unsigned int port, const void *from, int len)
 {
-	panic("outsl not supported on this architecture");
+	u32 off = port << 1;
+
+	if (SUPERIO_PORT(port) || port & 3)
+		BUG();
+
+	__raw_writesw(ISAIO_BASE + off, from, len << 1);
 }
 
 void insl(unsigned int port, void *from, int len)
 {
-	panic("insl not supported on this architecture");
+	u32 off = port << 1;
+
+	if (SUPERIO_PORT(port) || port & 3)
+		BUG();
+
+	__raw_readsw(ISAIO_BASE + off, from, len << 1);
 }
+
+EXPORT_SYMBOL(outsl);
+EXPORT_SYMBOL(insl);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-epxa10db/arch.c linux/arch/arm/mach-epxa10db/arch.c
--- linux.orig/arch/arm/mach-epxa10db/arch.c	Thu Oct 25 20:53:45 2001
+++ linux/arch/arm/mach-epxa10db/arch.c	Tue May 28 22:39:29 2002
@@ -18,7 +18,6 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-epxa10db/mm.c linux/arch/arm/mach-epxa10db/mm.c
--- linux.orig/arch/arm/mach-epxa10db/mm.c	Thu Oct 25 20:53:45 2001
+++ linux/arch/arm/mach-epxa10db/mm.c	Tue May 28 22:39:29 2002
@@ -27,6 +27,7 @@
 #include <asm/io.h>
 #include <asm/pgtable.h>
 #include <asm/page.h>
+#include <asm/sizes.h>
  
 #include <asm/mach/map.h>
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-integrator/pci_v3.c linux/arch/arm/mach-integrator/pci_v3.c
--- linux.orig/arch/arm/mach-integrator/pci_v3.c	Thu Oct 11 16:04:57 2001
+++ linux/arch/arm/mach-integrator/pci_v3.c	Tue May 28 22:39:18 2002
@@ -20,6 +20,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
+#include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
@@ -411,12 +412,19 @@
 	flags:	IORESOURCE_MEM | IORESOURCE_PREFETCH,
 };
 
-void __init pci_v3_setup_resources(struct resource **resource)
+int __init pci_v3_setup_resources(struct resource **resource)
 {
-	if (request_resource(&iomem_resource, &non_mem))
-		printk("PCI: unable to allocate non-prefetchable memory region\n");
-	if (request_resource(&iomem_resource, &pre_mem))
-		printk("PCI: unable to allocate prefetchable memory region\n");
+	if (request_resource(&iomem_resource, &non_mem)) {
+		printk(KERN_ERR "PCI: unable to allocate non-prefetchable "
+		       "memory region\n");
+		return -EBUSY;
+	}
+	if (request_resource(&iomem_resource, &pre_mem)) {
+		release_resource(&non_mem);
+		printk(KERN_ERR "PCI: unable to allocate prefetchable "
+		       "memory region\n");
+		return -EBUSY;
+	}
 
 	/*
 	 * bus->resource[0] is the IO resource for this bus
@@ -426,6 +434,8 @@
 	resource[0] = &ioport_resource;
 	resource[1] = &non_mem;
 	resource[2] = &pre_mem;
+
+	return 1;
 }
 
 /*
@@ -433,18 +443,23 @@
  * means I can't get additional information on the reason for the pm2fb
  * problems.  I suppose I'll just have to mind-meld with the machine. ;)
  */
-#define SC_PCI     (IO_ADDRESS(INTEGRATOR_SC_PCIENABLE))
-#define SC_LBFADDR (IO_ADDRESS(INTEGRATOR_SC_BASE+0x20))
-#define SC_LBFCODE (IO_ADDRESS(INTEGRATOR_SC_BASE+0x24))
+#define SC_PCI     (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_PCIENABLE_OFFSET)
+#define SC_LBFADDR (IO_ADDRESS(INTEGRATOR_SC_BASE) + 0x20)
+#define SC_LBFCODE (IO_ADDRESS(INTEGRATOR_SC_BASE) + 0x24)
 
 static int v3_fault(unsigned long addr, struct pt_regs *regs)
 {
 	unsigned long pc = instruction_pointer(regs);
 	unsigned long instr = *(unsigned long *)pc;
+#if 0
+	char buf[128];
 
-	printk("V3 fault: address=0x%08lx, pc=0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x ISTAT=%02x\n",
+	sprintf(buf, "V3 fault: address=0x%08lx, pc=0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x ISTAT=%02x\n",
 		addr, pc, instr, __raw_readl(SC_LBFADDR), __raw_readl(SC_LBFCODE) & 255,
 		v3_readb(V3_LB_ISTAT));
+	printk(KERN_DEBUG "%s", buf);
+	printascii(buf);
+#endif
 
 	v3_writeb(V3_LB_ISTAT, 0);
 	__raw_writel(3, SC_PCI);
@@ -467,11 +482,20 @@
 		return 0;
 	}
 
+	if ((instr & 0x0e100090) == 0x00100090) {
+		int reg = (instr >> 12) & 15;
+
+		regs->uregs[reg] = -1;
+		regs->ARM_pc += 4;
+		return 0;
+	}
+
 	return 1;
 }
 
 static void v3_irq(int irq, void *devid, struct pt_regs *regs)
 {
+#ifdef CONFIG_DEBUG_LL
 	unsigned long pc = instruction_pointer(regs);
 	unsigned long instr = *(unsigned long *)pc;
 	char buf[128];
@@ -480,10 +504,13 @@
 		pc, instr, __raw_readl(SC_LBFADDR), __raw_readl(SC_LBFCODE) & 255,
 		v3_readb(V3_LB_ISTAT));
 	printascii(buf);
+#endif
 
+	v3_writew(V3_PCI_STAT, 0xf000);
 	v3_writeb(V3_LB_ISTAT, 0);
 	__raw_writel(3, SC_PCI);
 
+#ifdef CONFIG_DEBUG_LL
 	/*
 	 * If the instruction being executed was a read,
 	 * make it look like it read all-ones.
@@ -493,17 +520,9 @@
 		sprintf(buf, "   reg%d = %08lx\n", reg, regs->uregs[reg]);
 		printascii(buf);
 	}
+#endif
 }
 
-static struct irqaction v3_int = {
-	name: "V3",
-	handler: v3_irq,
-};
-static struct irqaction v3_int2 = {
-	name: "V3TM",
-	handler: v3_irq,
-};
-
 extern int (*external_fault)(unsigned long addr, struct pt_regs *regs);
 
 /*
@@ -514,6 +533,8 @@
 {
 	unsigned int pci_cmd;
 	unsigned long flags;
+	unsigned int temp;
+	int ret;
 
 	/*
 	 * Hook in our fault handler for PCI errors
@@ -523,6 +544,12 @@
 	spin_lock_irqsave(&v3_lock, flags);
 
 	/*
+	 * Unlock V3 registers, but only if they were previously locked.
+	 */
+	if (v3_readw(V3_SYSTEM) & V3_SYSTEM_M_LOCK)
+		v3_writew(V3_SYSTEM, 0xa05f);
+
+	/*
 	 * Setup window 0 - PCI non-prefetchable memory
 	 *  Local: 0x40000000 Bus: 0x00000000 Size: 256MB
 	 */
@@ -548,6 +575,45 @@
 			V3_LB_BASE_ENABLE);
 	v3_writew(V3_LB_MAP2, v3_addr_to_lb_map2(0));
 
+	/*
+	 * Disable PCI to host IO cycles
+	 */
+	temp = v3_readw(V3_PCI_CFG) & ~V3_PCI_CFG_M_I2O_EN;
+	temp |= V3_PCI_CFG_M_IO_REG_DIS | V3_PCI_CFG_M_IO_DIS;
+	v3_writew(V3_PCI_CFG, temp);
+
+	printk(KERN_DEBUG "FIFO_CFG: %04x  FIFO_PRIO: %04x\n",
+		v3_readw(V3_FIFO_CFG), v3_readw(V3_FIFO_PRIORITY));
+
+	/*
+	 * Set the V3 FIFO such that writes have higher priority than
+	 * reads, and local bus write causes local bus read fifo flush.
+	 * Same for PCI.
+	 */
+	v3_writew(V3_FIFO_PRIORITY, 0x0a0a);
+
+	/*
+	 * Re-lock the system register.
+	 */
+	temp = v3_readw(V3_SYSTEM) | V3_SYSTEM_M_LOCK;
+	v3_writew(V3_SYSTEM, temp);
+
+	/*
+	 * Clear any error conditions, and enable write errors.
+	 */
+	v3_writeb(V3_LB_ISTAT, 0);
+	v3_writew(V3_LB_CFG, v3_readw(V3_LB_CFG) | (1 << 10));
+	v3_writeb(V3_LB_IMASK, 0x28);
+	__raw_writel(3, SC_PCI);
+
+	/*
+	 * Grab the PCI error interrupt.
+	 */
+	ret = request_irq(IRQ_V3INT, v3_irq, 0, "V3 error", NULL);
+	if (ret)
+		printk(KERN_ERR "PCI: unable to grab PCI error "
+		       "interrupt: %d\n", ret);
+
 	spin_unlock_irqrestore(&v3_lock, flags);
 
 	pci_scan_bus(0, &pci_v3_ops, sysdata);
@@ -557,18 +623,13 @@
 
 	v3_writew(V3_PCI_CMD, pci_cmd);
 
-	/*
-	 * Clear any error conditions.
-	 */
-	__raw_writel(3, SC_PCI);
-	v3_writew(V3_LB_CFG, v3_readw(V3_LB_CFG) | (1 << 10));
-	v3_writeb(V3_LB_ISTAT, 0);
+	v3_writeb(V3_LB_ISTAT, ~0x40);
 	v3_writeb(V3_LB_IMASK, 0x68);
 
-	printk("LB_CFG: %04x LB_ISTAT: %02x LB_IMASK: %02x\n",
-		v3_readw(V3_LB_CFG),
-		v3_readb(V3_LB_ISTAT),
-		v3_readb(V3_LB_IMASK));
-	setup_arm_irq(IRQ_V3INT, &v3_int);
-//	setup_arm_irq(IRQ_LBUSTIMEOUT, &v3_int2);
+#if 0
+	ret = request_irq(IRQ_LBUSTIMEOUT, lb_timeout, 0, "bus timeout", NULL);
+	if (ret)
+		printk(KERN_ERR "PCI: unable to grab local bus timeout ".
+		       "interrupt: %d\n", ret);
+#endif
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-mx1ads/Makefile linux/arch/arm/mach-mx1ads/Makefile
--- linux.orig/arch/arm/mach-mx1ads/Makefile	Thu Jan  1 00:00:00 1970
+++ linux/arch/arm/mach-mx1ads/Makefile	Tue May 28 22:39:24 2002
@@ -0,0 +1,20 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET		:= mx1ads.o
+
+# Object file lists.
+
+obj-y			:= arch.o cpu.o irq.o mm.o time.o
+obj-m			:=
+obj-n			:=
+obj-			:=
+
+
+include $(TOPDIR)/Rules.make
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-mx1ads/arch.c linux/arch/arm/mach-mx1ads/arch.c
--- linux.orig/arch/arm/mach-mx1ads/arch.c	Thu Jan  1 00:00:00 1970
+++ linux/arch/arm/mach-mx1ads/arch.c	Tue May 28 22:39:27 2002
@@ -0,0 +1,59 @@
+/*
+ *  linux/arch/arm/mach-mx1ads/arch.c
+ *
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/amba_kmi.h>
+
+extern void mx1ads_map_io(void);
+extern void mx1ads_init_irq(void);
+
+
+static void __init
+mx1ads_fixup(struct machine_desc *desc, struct param_struct *unused,
+		 char **cmdline, struct meminfo *mi)
+{
+}
+
+MACHINE_START(MX1ADS, "Motorola MX1ADS")
+	MAINTAINER("Shane Nay")
+#ifdef CONFIG_ARCH_MX1ADS_SRAM
+	BOOT_MEM(0x12000000, 0x00200000, 0xf0200000)
+#else
+	BOOT_MEM(0x08000000, 0x00200000, 0xf0200000)
+#endif
+	FIXUP(mx1ads_fixup)
+	MAPIO(mx1ads_map_io)
+	INITIRQ(mx1ads_init_irq)
+MACHINE_END
+
+#if 0
+
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-mx1ads/cpu.c linux/arch/arm/mach-mx1ads/cpu.c
--- linux.orig/arch/arm/mach-mx1ads/cpu.c	Thu Jan  1 00:00:00 1970
+++ linux/arch/arm/mach-mx1ads/cpu.c	Tue May 28 22:39:24 2002
@@ -0,0 +1,34 @@
+/*
+ *  linux/arch/arm/mach-mx1ads/cpu.c
+ *
+ *  Copyright (C) 2001 Deep Blue Solutions Ltd.
+ *
+ *  $Id: cpu.c,v 1.2 2001/09/22 12:11:17 rmk Exp $
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * CPU support functions
+ */
+
+/*  FIXME-
+ *  Add support for clock change on the fly.  (Power)
+ *
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/cpufreq.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+
+static int __init cpu_init(void)
+{
+	return 0;
+}
+
+__initcall(cpu_init);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-mx1ads/irq.c linux/arch/arm/mach-mx1ads/irq.c
--- linux.orig/arch/arm/mach-mx1ads/irq.c	Thu Jan  1 00:00:00 1970
+++ linux/arch/arm/mach-mx1ads/irq.c	Tue May 28 22:39:29 2002
@@ -0,0 +1,73 @@
+/*
+ *  linux/arch/arm/mach-mx1ads/irq.c
+ *
+ *  Copyright (C) 1999 ARM Limited
+ *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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
+ */
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/mach/irq.h>
+
+/*
+ *
+ * We simply use the ENABLE DISABLE registers inside of the MX1
+ * to turn on/off specific interrupts.  FIXME- We should
+ * also add support for the accelerated interrupt controller
+ * by putting offets to irq jump code in the appropriate
+ * places.
+ *
+ */
+
+#define INTENNUM_OFF              0x8
+#define INTDISNUM_OFF             0xC
+
+#define VA_AITC_BASE              IO_ADDRESS(MX1ADS_AITC_BASE)
+#define MX1ADS_AITC_INTDISNUM     (VA_AITC_BASE + INTDISNUM_OFF)
+#define MX1ADS_AITC_INTENNUM      (VA_AITC_BASE + INTENNUM_OFF)
+
+static void
+mx1ads_mask_irq(unsigned int irq)
+{
+	__raw_writel(irq, MX1ADS_AITC_INTDISNUM);
+}
+
+static void
+mx1ads_unmask_irq(unsigned int irq)
+{
+	__raw_writel(irq, MX1ADS_AITC_INTENNUM);
+}
+
+void __init
+mx1ads_init_irq(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < NR_IRQS; i++) {
+		irq_desc[i].valid = 1;
+		irq_desc[i].probe_ok = 1;
+		irq_desc[i].mask_ack = mx1ads_mask_irq;
+		irq_desc[i].mask = mx1ads_mask_irq;
+		irq_desc[i].unmask = mx1ads_unmask_irq;
+	}
+
+	/* Disable all interrupts initially. */
+	/* In MX1 this is done in the bootloader. */
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-mx1ads/mm.c linux/arch/arm/mach-mx1ads/mm.c
--- linux.orig/arch/arm/mach-mx1ads/mm.c	Thu Jan  1 00:00:00 1970
+++ linux/arch/arm/mach-mx1ads/mm.c	Tue May 28 22:39:31 2002
@@ -0,0 +1,45 @@
+/*
+ *  linux/arch/arm/mach-mx1ads/mm.c
+ *
+ *  Copyright (C) 1999,2000 Arm Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+
+#include <asm/mach/map.h>
+
+
+
+static struct map_desc mx1ads_io_desc[] __initdata = {
+
+  { IO_ADDRESS(MX1ADS_SRAM_BASE),     MX1ADS_SRAM_BASE,      SZ_128K   , DOMAIN_IO, 0, 1},
+  { IO_ADDRESS(MX1ADS_IO_BASE),       MX1ADS_IO_BASE,        SZ_256K   , DOMAIN_IO, 0, 1},
+  LAST_DESC
+};
+
+void __init mx1ads_map_io(void)
+{
+	iotable_init(mx1ads_io_desc);
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-mx1ads/time.c linux/arch/arm/mach-mx1ads/time.c
--- linux.orig/arch/arm/mach-mx1ads/time.c	Thu Jan  1 00:00:00 1970
+++ linux/arch/arm/mach-mx1ads/time.c	Tue May 28 22:39:13 2002
@@ -0,0 +1,45 @@
+/*
+ *  linux/arch/arm/mach-mx1ads/time.c
+ *
+ *  Copyright (C) 2000-2001 Deep Blue Solutions
+ *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+
+extern int (*set_rtc)(void);
+
+/* FIXME-
+ * When we have an external RTC part,
+ * put the mapping in for that part.
+ *
+ * The internal RTC within the MX1 is not sufficient
+ * for tracking time other than time of day, or
+ * date over very short periods of time.
+ *
+ */
+
+static int mx1ads_set_rtc(void)
+{
+	return 0;
+}
+
+static int mx1ads_rtc_init(void)
+{
+	xtime.tv_sec = 0;
+
+	set_rtc = mx1ads_set_rtc;
+
+	return 0;
+}
+
+__initcall(mx1ads_rtc_init);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/Makefile linux/arch/arm/mach-sa1100/Makefile
--- linux.orig/arch/arm/mach-sa1100/Makefile	Thu Oct 25 20:53:45 2001
+++ linux/arch/arm/mach-sa1100/Makefile	Tue May 28 22:39:31 2002
@@ -9,20 +9,19 @@
 
 O_TARGET		:= sa1100.o
 
-obj-y :=
+# Common support (must be linked before board specific support)
+obj-y := generic.o irq.o dma-sa1100.o
 obj-m :=
 obj-n :=
 obj-  :=
 
-export-objs :=	assabet.o dma-sa1100.o dma-sa1111.o freebird.o generic.o \
-		h3600.o huw_webpanel.o irq.o pcipool.o sa1111-pcibuf.o   \
-		yopy.o
+export-objs :=	assabet.o dma-sa1100.o dma-sa1111.o \
+		flexanet.o freebird.o generic.o h3600.o \
+		huw_webpanel.o irq.o pcipool.o sa1111.o sa1111-pcibuf.o \
+		system3.o yopy.o usb_ctl.o usb_recv.o usb_send.o
 
 # These aren't present yet, and prevents a plain -ac kernel building.
-# hwtimer.o usb_ctl.o usb_recv.o usb_send.o
-
-# Common support (must be linked before board specific support)
-obj-y += generic.o irq.o dma-sa1100.o
+# hwtimer.o
 
 # This needs to be cleaned up.  We probably need to have SA1100
 # and SA1110 config symbols.
@@ -31,6 +30,7 @@
 ifeq ($(CONFIG_CPU_FREQ),y)
 obj-$(CONFIG_SA1100_ASSABET) += cpu-sa1110.o
 obj-$(CONFIG_SA1100_CERF) += cpu-sa1110.o
+obj-$(CONFIG_SA1100_PT_SYSTEM3) += cpu-sa1110.o
 obj-$(CONFIG_SA1100_LART) += cpu-sa1100.o
 endif
 
@@ -42,11 +42,13 @@
 obj-$(CONFIG_SA1100_ADSBITSY) += adsbitsy.o
 obj-$(CONFIG_SA1100_ASSABET) += assabet.o
 obj-$(CONFIG_ASSABET_NEPONSET) += neponset.o
+obj-$(CONFIG_SA1100_BADGE4) +=  badge4.o
 obj-$(CONFIG_SA1100_BRUTUS) += brutus.o
 obj-$(CONFIG_SA1100_CERF) += cerf.o
 obj-$(CONFIG_SA1100_EMPEG) += empeg.o
 obj-$(CONFIG_SA1100_FLEXANET) += flexanet.o
 obj-$(CONFIG_SA1100_FREEBIRD) += freebird.o
+obj-$(CONFIG_SA1100_FRODO) += frodo.o
 obj-$(CONFIG_SA1100_GRAPHICSCLIENT) += graphicsclient.o
 obj-$(CONFIG_SA1100_GRAPHICSMASTER) += graphicsmaster.o
 obj-$(CONFIG_SA1100_H3600) += h3600.o
@@ -59,6 +61,8 @@
 obj-$(CONFIG_SA1100_PANGOLIN) += pangolin.o
 obj-$(CONFIG_SA1100_PFS168) += pfs168.o
 obj-$(CONFIG_SA1100_PLEB) += pleb.o
+obj-$(CONFIG_SA1100_PT_SYSTEM3) += system3.o
+obj-$(CONFIG_SA1100_SHANNON) += shannon.o
 obj-$(CONFIG_SA1100_SHERMAN) += sherman.o
 obj-$(CONFIG_SA1100_SIMPAD) += simpad.o
 obj-$(CONFIG_SA1100_VICTOR) += victor.o
@@ -72,14 +76,27 @@
 leds-$(CONFIG_SA1100_BRUTUS) += leds-brutus.o
 leds-$(CONFIG_SA1100_CERF) += leds-cerf.o
 leds-$(CONFIG_SA1100_FLEXANET) += leds-flexanet.o
+leds-$(CONFIG_SA1100_FRODO) += leds-frodo.o
 leds-$(CONFIG_SA1100_GRAPHICSCLIENT) += leds-graphicsclient.o
 leds-$(CONFIG_SA1100_GRAPHICSMASTER) += leds-graphicsmaster.o
 leds-$(CONFIG_SA1100_LART) += leds-lart.o
 leds-$(CONFIG_SA1100_PFS168) += leds-pfs168.o
 leds-$(CONFIG_SA1100_SIMPAD) += leds-simpad.o  
+leds-$(CONFIG_SA1100_PT_SYSTEM3) += leds-system3.o
 obj-$(CONFIG_LEDS) += $(leds-y)
 
+# SA1110 USB client support
+list-multi += sa1100usb_core.o
+sa1100usb_core-objs := usb_ctl.o usb_ep0.o usb_recv.o usb_send.o
+obj-$(CONFIG_SA1100_USB) += sa1100usb_core.o
+obj-$(CONFIG_SA1100_USB_NETLINK) += usb-eth.o
+obj-$(CONFIG_SA1100_USB_CHAR) += usb-char.o
+
 # Miscelaneous functions
 obj-$(CONFIG_PM) += pm.o sleep.o
 
 include $(TOPDIR)/Rules.make
+
+sa1100usb_core.o: $(sa1100usb_core-objs)
+	$(LD) -r -o $@ $(sa1100usb_core-objs)
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/adsbitsy.c linux/arch/arm/mach-sa1100/adsbitsy.c
--- linux.orig/arch/arm/mach-sa1100/adsbitsy.c	Thu Oct 11 16:04:57 2001
+++ linux/arch/arm/mach-sa1100/adsbitsy.c	Tue May 28 22:39:13 2002
@@ -53,7 +53,7 @@
 	/*
 	 * Probe for SA1111.
 	 */
-	ret = sa1111_probe();
+	ret = sa1111_probe(ADSBITSY_SA1111_BASE);
 	if (ret < 0)
 		return ret;
 
@@ -94,7 +94,7 @@
 	sa1110_mb_enable();
 
 	set_GPIO_IRQ_edge(GPIO_GPIO0, GPIO_RISING_EDGE);
-	sa1111_init_irq(SA1100_GPIO_TO_IRQ(0));
+	sa1111_init_irq(IRQ_GPIO0);
 
 	return 0;
 }
@@ -126,8 +126,8 @@
 
 static struct map_desc adsbitsy_io_desc[] __initdata = {
  /* virtual     physical    length      domain     r  w  c  b */
-  { 0xe8000000, 0x08000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */
-  { 0xf4000000, 0x18000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* SA1111 */
+  { 0xe8000000, 0x08000000, 0x01000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 1 */
+  { 0xf4000000, 0x18000000, 0x00800000, DOMAIN_IO, 0, 1, 0, 0 }, /* SA1111 */
   LAST_DESC
 };
 
@@ -135,24 +135,15 @@
 {
 	if (port->mapbase == _Ser1UTCR0) {
 		Ser1SDCR0 |= SDCR0_UART;
-		// Set RTS Output and High (should be done in the set_mctrl fn)
-		GPDR |= GPIO_GPIO15;
-		GPCR |= GPIO_GPIO15;
-		// Set CTS Input
-		GPDR &= ~GPIO_GPIO14;
+#error Fixme	// Set RTS High (should be done in the set_mctrl fn)
+		GPCR = GPIO_GPIO15;
 	} else if (port->mapbase == _Ser2UTCR0) {
 		Ser2UTCR4 = Ser2HSCR0 = 0;
-		// Set RTS Output and High (should be done in the set_mctrl fn)
-		GPDR |= GPIO_GPIO17;
-		GPCR |= GPIO_GPIO17;
-		// Set CTS Input
-		GPDR &= ~GPIO_GPIO16;
+#error Fixme	// Set RTS High (should be done in the set_mctrl fn)
+		GPCR = GPIO_GPIO17;
 	} else if (port->mapbase == _Ser2UTCR0) {
-		// Set RTS Output and High (should be done in the set_mctrl fn)
-		GPDR |= GPIO_GPIO19;
-		GPCR |= GPIO_GPIO19;
-		// Set CTS Input
-		GPDR &= ~GPIO_GPIO18;
+#error Fixme	// Set RTS High (should be done in the set_mctrl fn)
+		GPCR = GPIO_GPIO19;
 	}
 	return 0;
 }
@@ -166,10 +157,12 @@
 	sa1100_map_io();
 	iotable_init(adsbitsy_io_desc);
 
-	sa1110_register_uart_fns(&adsbitsy_port_fns);
+	sa1100_register_uart_fns(&adsbitsy_port_fns);
 	sa1100_register_uart(0, 3);
 	sa1100_register_uart(1, 1);
 	sa1100_register_uart(2, 2);
+	GPDR |= GPIO_GPIO15 | GPIO_GPIO17 | GPIO_GPIO19;
+	GPDR &= ~(GPIO_GPIO14 | GPIO_GPIO16 | GPIO_GPIO18);
 }
 
 MACHINE_START(ADSBITSY, "ADS Bitsy")
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/assabet.c linux/arch/arm/mach-sa1100/assabet.c
--- linux.orig/arch/arm/mach-sa1100/assabet.c	Thu Oct 25 20:53:45 2001
+++ linux/arch/arm/mach-sa1100/assabet.c	Tue May 28 22:39:13 2002
@@ -31,16 +31,48 @@
 
 #include "generic.h"
 
+#define ASSABET_BCR_DB1110 \
+	(ASSABET_BCR_SPK_OFF    | ASSABET_BCR_QMUTE     | \
+	 ASSABET_BCR_LED_GREEN  | ASSABET_BCR_LED_RED   | \
+	 ASSABET_BCR_RS232EN    | ASSABET_BCR_LCD_12RGB | \
+	 ASSABET_BCR_IRDA_MD0)
+
+#define ASSABET_BCR_DB1111 \
+	(ASSABET_BCR_SPK_OFF    | ASSABET_BCR_QMUTE     | \
+	 ASSABET_BCR_LED_GREEN  | ASSABET_BCR_LED_RED   | \
+	 ASSABET_BCR_RS232EN    | ASSABET_BCR_LCD_12RGB | \
+	 ASSABET_BCR_CF_BUS_OFF | ASSABET_BCR_STEREO_LB | \
+	 ASSABET_BCR_IRDA_MD0   | ASSABET_BCR_CF_RST)
 
-unsigned long BCR_value = ASSABET_BCR_DB1110;
 unsigned long SCR_value = ASSABET_SCR_INIT;
-EXPORT_SYMBOL(BCR_value);
 EXPORT_SYMBOL(SCR_value);
 
+static unsigned long BCR_value = ASSABET_BCR_DB1110;
+
+void ASSABET_BCR_frob(unsigned int mask, unsigned int val)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	BCR_value = (BCR_value & ~mask) | val;
+	ASSABET_BCR = BCR_value;
+	local_irq_restore(flags);
+}
+
+EXPORT_SYMBOL(ASSABET_BCR_frob);
+
 
 static int __init assabet_init(void)
 {
-	if (machine_is_assabet() && machine_has_neponset()) {
+	if (!machine_is_assabet())
+		return -EINVAL;
+
+	/*
+	 * Set the IRQ edges
+	 */
+	set_GPIO_IRQ_edge(GPIO_GPIO23, GPIO_RISING_EDGE);	/* UCB1300 */
+
+	if (machine_has_neponset()) {
 		/*
 		 * Angel sets this, but other bootloaders may not.
 		 *
@@ -55,6 +87,7 @@
 			"hasn't been configured in the kernel\n" );
 #endif
 	}
+
 	return 0;
 }
 
@@ -87,18 +120,18 @@
  * repeat it here because the kernel may not be loaded as a zImage, and
  * also because it's a hassle to communicate the SCR value to the kernel
  * from the decompressor.
+ *
+ * Note that IRQs are guaranteed to be disabled.
  */
 static void __init get_assabet_scr(void)
 {
-	unsigned long flags, scr, i;
+	unsigned long scr, i;
 
-	local_irq_save(flags);
 	GPDR |= 0x3fc;			/* Configure GPIO 9:2 as outputs */
 	GPSR = 0x3fc;			/* Write 0xFF to GPIO 9:2 */
 	GPDR &= ~(0x3fc);		/* Configure GPIO 9:2 as inputs */
 	for(i = 100; i--; scr = GPLR);	/* Read GPIO 9:2 */
 	GPDR |= 0x3fc;			/*  restore correct pin direction */
-	local_irq_restore(flags);
 	scr &= 0x3fc;			/* save as system configuration byte. */
 	SCR_value = scr;
 }
@@ -174,9 +207,9 @@
 
 static struct map_desc assabet_io_desc[] __initdata = {
  /* virtual     physical    length      domain     r  w  c  b */
-  { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */
-  { 0xf1000000, 0x12000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* Board Control Register */
-  { 0xf2800000, 0x4b800000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* MQ200 */
+  { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 0 */
+  { 0xf1000000, 0x12000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* Board Control Register */
+  { 0xf2800000, 0x4b800000, 0x00800000, DOMAIN_IO, 0, 1, 0, 0 }, /* MQ200 */
   /*  f3000000 - neponset system registers */
   /*  f4000000 - neponset SA1111 registers */
   LAST_DESC
@@ -186,19 +219,18 @@
 {
 	if (port->mapbase == _Ser1UTCR0) {
 		if (state)
-			ASSABET_BCR_clear(ASSABET_BCR_RS232EN);
+			ASSABET_BCR_clear(ASSABET_BCR_RS232EN |
+					  ASSABET_BCR_COM_RTS |
+					  ASSABET_BCR_COM_DTR);
 		else
-			ASSABET_BCR_set(ASSABET_BCR_RS232EN);
+			ASSABET_BCR_set(ASSABET_BCR_RS232EN |
+					ASSABET_BCR_COM_RTS |
+					ASSABET_BCR_COM_DTR);
 	}
 }
 
 /*
- * Note! this can be called from IRQ context.
- * FIXME: You _need_ to handle ASSABET_BCR carefully, which doesn't
- * happen at the moment.  Suggest putting interrupt save/restore
- * in ASSABET_BCR_set/clear.
- *
- * NB: Assabet uses COM_RTS and COM_DTR for both UART1 (com port)
+ * Assabet uses COM_RTS and COM_DTR for both UART1 (com port)
  * and UART3 (radio module).  We only handle them for UART1 here.
  */
 static void assabet_set_mctrl(struct uart_port *port, u_int mctrl)
@@ -207,21 +239,21 @@
 		u_int set = 0, clear = 0;
 
 		if (mctrl & TIOCM_RTS)
-			set |= ASSABET_BCR_COM_RTS;
-		else
 			clear |= ASSABET_BCR_COM_RTS;
+		else
+			set |= ASSABET_BCR_COM_RTS;
 
 		if (mctrl & TIOCM_DTR)
-			set |= ASSABET_BCR_COM_DTR;
-		else
 			clear |= ASSABET_BCR_COM_DTR;
+		else
+			set |= ASSABET_BCR_COM_DTR;
 
 		ASSABET_BCR_clear(clear);
 		ASSABET_BCR_set(set);
 	}
 }
 
-static int assabet_get_mctrl(struct uart_port *port)
+static u_int assabet_get_mctrl(struct uart_port *port)
 {
 	u_int ret = 0;
 	u_int bsr = ASSABET_BSR;
@@ -312,11 +344,7 @@
 	PWER = PWER_GPIO0;
 	PGSR = 0;
 	PCFR = 0;
-
-	/*
-	 * Clear all possible wakeup reasons.
-	 */
-	RCSR = RCSR_HWR | RCSR_SWR | RCSR_WDR | RCSR_SMR;
+	PSDR = 0;
 }
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/badge4.c linux/arch/arm/mach-sa1100/badge4.c
--- linux.orig/arch/arm/mach-sa1100/badge4.c	Thu Jan  1 00:00:00 1970
+++ linux/arch/arm/mach-sa1100/badge4.c	Tue May 28 22:39:30 2002
@@ -0,0 +1,213 @@
+/*
+ * linux/arch/arm/mach-sa1100/badge4.c
+ *
+ * BadgePAD 4 specific initialization
+ *
+ *   Tim Connors <connors@hpl.hp.com>
+ *   Christopher Hoover <ch@hpl.hp.com>
+ *
+ * Copyright (C) 2002 Hewlett-Packard Company
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/tty.h>
+#include <linux/errno.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/arch/irqs.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/hardware/sa1111.h>
+#include <asm/mach/serial_sa1100.h>
+
+#include "generic.h"
+#include "sa1111.h"
+
+static int __init badge4_sa1111_init(void)
+{
+	int ret;
+
+	/*
+	 * Ensure that the memory bus request/grant signals are setup,
+	 * and the grant is held in its inactive state
+	 */
+	sa1110_mb_disable();
+
+	/*
+	 * Probe for SA1111.
+	 */
+	ret = sa1111_probe(BADGE4_SA1111_BASE);
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * We found it.  Wake the chip up.
+	 */
+	sa1111_wake();
+
+	/*
+	 * The SDRAM configuration of the SA1110 and the SA1111 must
+	 * match.  This is very important to ensure that SA1111 accesses
+	 * don't corrupt the SDRAM.  Note that this ungates the SA1111's
+	 * MBGNT signal, so we must have called sa1110_mb_disable()
+	 * beforehand.
+	 */
+	sa1111_configure_smc(1,
+			     FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
+			     FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
+
+	/*
+	 * We only need to turn on DCLK whenever we want to use the
+	 * DMA.  It can otherwise be held firmly in the off position.
+	 */
+	SKPCR |= SKPCR_DCLKEN;
+
+	/*
+	 * Enable the SA1110 memory bus request and grant signals.
+	 */
+	sa1110_mb_enable();
+
+	set_GPIO_IRQ_edge(BADGE4_GPIO_INT_1111, GPIO_RISING_EDGE);
+	sa1111_init_irq(BADGE4_IRQ_GPIO_SA1111);
+
+	return 0;
+}
+
+static int __init badge4_init(void)
+{
+	int ret;
+
+	if (!machine_is_badge4())
+		return -ENODEV;
+
+	ret = badge4_sa1111_init();
+	if (ret < 0)
+		printk(KERN_ERR __FUNCTION__
+		       ": SA-1111 initialization failed (%d)\n", ret);
+
+	/* N.B, according to rmk this is the singular place that GPDR
+           should be set */
+
+	/* Video expansion */
+	GPCR  = (BADGE4_GPIO_INT_VID | BADGE4_GPIO_LGP2 | BADGE4_GPIO_LGP3 |
+		 BADGE4_GPIO_LGP4 | BADGE4_GPIO_LGP5 | BADGE4_GPIO_LGP6 |
+		 BADGE4_GPIO_LGP7 | BADGE4_GPIO_LGP8 | BADGE4_GPIO_LGP9 |
+		 BADGE4_GPIO_GPA_VID | BADGE4_GPIO_GPB_VID |
+		 BADGE4_GPIO_GPC_VID);
+	GPDR |= (BADGE4_GPIO_INT_VID | BADGE4_GPIO_LGP2 | BADGE4_GPIO_LGP3 |
+		 BADGE4_GPIO_LGP4 | BADGE4_GPIO_LGP5 | BADGE4_GPIO_LGP6 |
+		 BADGE4_GPIO_LGP7 | BADGE4_GPIO_LGP8 | BADGE4_GPIO_LGP9 |
+		 BADGE4_GPIO_GPA_VID | BADGE4_GPIO_GPB_VID |
+		 BADGE4_GPIO_GPC_VID);
+
+	/* SDRAM SPD i2c */
+	GPCR  = (BADGE4_GPIO_SDSDA | BADGE4_GPIO_SDSCL);
+	GPDR |= (BADGE4_GPIO_SDSDA | BADGE4_GPIO_SDSCL);
+
+	/* uart */
+	GPCR  = (BADGE4_GPIO_UART_HS1 | BADGE4_GPIO_UART_HS2);
+	GPDR |= (BADGE4_GPIO_UART_HS1 | BADGE4_GPIO_UART_HS2);
+
+	/* drives CPLD muxsel0 input */
+	GPCR  = BADGE4_GPIO_MUXSEL0;
+	GPDR |= BADGE4_GPIO_MUXSEL0;
+
+	/* test points */
+	GPCR  = (BADGE4_GPIO_TESTPT_J7 | BADGE4_GPIO_TESTPT_J6 |
+		 BADGE4_GPIO_TESTPT_J5);
+	GPDR |= (BADGE4_GPIO_TESTPT_J7 | BADGE4_GPIO_TESTPT_J6 |
+		 BADGE4_GPIO_TESTPT_J5);
+
+	/* drives CPLD sdram type inputs; this shouldn't be needed;
+           bootloader left it this way. */
+	GPDR |= (BADGE4_GPIO_SDTYP0 | BADGE4_GPIO_SDTYP1);
+
+  	/* 5V supply rail. */
+  	GPCR  = BADGE4_GPIO_PCMEN5V;		/* initially off */
+   	GPDR |= BADGE4_GPIO_PCMEN5V;
+
+	/* drives SA1111 reset pin; this shouldn't be needed;
+           bootloader left it this way. */
+	GPSR  = BADGE4_GPIO_SA1111_NRST;
+	GPDR |= BADGE4_GPIO_SA1111_NRST;
+
+	return 0;
+}
+
+__initcall(badge4_init);
+
+
+static unsigned badge4_5V_bitmap = 0;
+
+void badge4_set_5V(unsigned subsystem, int on)
+{
+	unsigned long flags;
+	unsigned old_5V_bitmap;
+
+	local_irq_save(flags);
+
+	old_5V_bitmap = badge4_5V_bitmap;
+
+	if (on) {
+		badge4_5V_bitmap |= subsystem;
+	} else {
+		badge4_5V_bitmap &= ~subsystem;
+	}
+
+	/* detect on->off and off->on transitions */
+	if ((!old_5V_bitmap) && (badge4_5V_bitmap)) {
+		/* was off, now on */
+		printk(KERN_INFO __FUNCTION__ ": enabling 5V supply rail\n");
+		GPSR = BADGE4_GPIO_PCMEN5V;
+	} else if ((old_5V_bitmap) && (!badge4_5V_bitmap)) {
+		/* was on, now off */
+		printk(KERN_INFO __FUNCTION__ ": disabling 5V supply rail\n");
+		GPCR = BADGE4_GPIO_PCMEN5V;
+	}
+
+	local_irq_restore(flags);
+}
+EXPORT_SYMBOL(badge4_set_5V);
+
+
+static void __init
+fixup_badge4(struct machine_desc *desc, struct param_struct *params,
+	    char **cmdline, struct meminfo *mi)
+{
+	/* nothing needed here */
+}
+
+static struct map_desc badge4_io_desc[] __initdata = {
+  /*  virtual    physical    length      domain   r w c b		   */
+  {0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 0,1,0,0},/* Flash bank 0 */
+  {0xf1000000, 0x08000000, 0x00100000, DOMAIN_IO, 0,1,0,0},/* SRAM  bank 1 */
+  {0xf2000000, 0x10000000, 0x00100000, DOMAIN_IO, 0,1,0,0},/* SRAM  bank 2 */
+  {0xf4000000, 0x48000000, 0x00100000, DOMAIN_IO, 0,1,0,0},/* SA-1111      */
+  LAST_DESC
+};
+
+static void __init badge4_map_io(void)
+{
+	sa1100_map_io();
+	iotable_init(badge4_io_desc);
+
+	sa1100_register_uart(0, 3);
+	sa1100_register_uart(1, 1);
+}
+
+MACHINE_START(BADGE4, "Hewlett-Packard Laboratories BadgePAD 4")
+	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+	BOOT_PARAMS(0xc0000100)
+	FIXUP(fixup_badge4)
+	MAPIO(badge4_map_io)
+	INITIRQ(sa1100_init_irq)
+MACHINE_END
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/cerf.c linux/arch/arm/mach-sa1100/cerf.c
--- linux.orig/arch/arm/mach-sa1100/cerf.c	Thu Oct 25 20:53:46 2001
+++ linux/arch/arm/mach-sa1100/cerf.c	Tue May 28 22:39:26 2002
@@ -1,7 +1,7 @@
 /*
  * linux/arch/arm/mach-sa1100/cerf.c
  */
-
+#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/tty.h>
@@ -16,20 +16,22 @@
 #include "generic.h"
 
 
-static void __init cerf_init_irq (void)
+static void __init cerf_init_irq(void)
 {
-  sa1100_init_irq();
+	sa1100_init_irq();
 
-  /* Need to register these as rising edge interrupts
-   * For standard 16550 serial driver support
-   * Basically - I copied it from pfs168.c :)
-   */
+	/* Need to register these as rising edge interrupts
+	 * For standard 16550 serial driver support
+	 * Basically - I copied it from pfs168.c :)
+	 */
 #ifdef CONFIG_SA1100_CERF_CPLD
-  set_GPIO_IRQ_edge(GPIO_GPIO(3), GPIO_RISING_EDGE); /* PDA Full serial port */
-  set_GPIO_IRQ_edge(GPIO_GPIO(2), GPIO_RISING_EDGE); /* PDA Bluetooth */
-  GPDR &= ~(GPIO_GPIO(3)); /* Set the direction of serial port GPIO pin to in */
-  GPDR &= ~(GPIO_GPIO(2)); /* Set the direction of bluetooth GPIO pin to in */
+	/* PDA Full serial port */
+	set_GPIO_IRQ_edge(GPIO_GPIO3, GPIO_RISING_EDGE);
+	/* PDA Bluetooth */
+	set_GPIO_IRQ_edge(GPIO_GPIO2, GPIO_RISING_EDGE);
 #endif /* CONFIG_SA1100_CERF_CPLD */
+
+	set_GPIO_IRQ_edge(GPIO_UCB1200_IRQ, GPIO_RISING_EDGE);
 }
 
 static void __init
@@ -37,22 +39,20 @@
 	   char **cmdline, struct meminfo *mi)
 {
 #if defined(CONFIG_SA1100_CERF_64MB)
-        // 64MB RAM
-        SET_BANK( 0, 0xc0000000, 64*1024*1024 );
-        mi->nr_banks = 1;
-#elif defined(CONFIG_SA1100_CERF_32MB)	// 32MB RAM
+	SET_BANK( 0, 0xc0000000, 64*1024*1024 );
+	mi->nr_banks = 1;
+#elif defined(CONFIG_SA1100_CERF_32MB)
 	SET_BANK( 0, 0xc0000000, 32*1024*1024 );
 	mi->nr_banks = 1;
-#elif defined(CONFIG_SA1100_CERF_16MB)	// 16Meg Ram.
+#elif defined(CONFIG_SA1100_CERF_16MB)
 	SET_BANK( 0, 0xc0000000, 8*1024*1024 );
 	SET_BANK( 1, 0xc8000000, 8*1024*1024 );
 	mi->nr_banks = 2;
 #elif defined(CONFIG_SA1100_CERF_8MB)
-        // 8Meg Ram.
-        SET_BANK( 0, 0xc0000000, 8*1024*1024 );
-        mi->nr_banks = 1;
+	SET_BANK( 0, 0xc0000000, 8*1024*1024 );
+	mi->nr_banks = 1;
 #else
-       #error "Undefined memory size for Cerfboard."
+#error "Undefined memory size for Cerfboard."
 #endif
 
 //	ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
@@ -62,13 +62,13 @@
 }
 
 static struct map_desc cerf_io_desc[] __initdata = {
-  /* virtual     physical    length      domain     r  w  c  b */
-  { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */
-  { 0xf0000000, 0x08000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* Crystal Ethernet Chip */
+  /* virtual	 physical    length	 domain     r  w  c  b */
+  { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 0 */
+  { 0xf0000000, 0x08000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* Crystal Ethernet Chip */
 #ifdef CONFIG_SA1100_CERF_CPLD
-  { 0xf1000000, 0x40000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* CPLD Chip */
-  { 0xf2000000, 0x10000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* CerfPDA Bluetooth */
-  { 0xf3000000, 0x18000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* CerfPDA Serial */
+  { 0xf1000000, 0x40000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* CPLD Chip */
+  { 0xf2000000, 0x10000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* CerfPDA Bluetooth */
+  { 0xf3000000, 0x18000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* CerfPDA Serial */
 #endif
   LAST_DESC
 };
@@ -78,12 +78,18 @@
 	sa1100_map_io();
 	iotable_init(cerf_io_desc);
 
-        sa1100_register_uart(0, 3);
+	sa1100_register_uart(0, 3);
 #ifdef CONFIG_SA1100_CERF_IRDA_ENABLED
 	sa1100_register_uart(1, 1);
 #else
 	sa1100_register_uart(1, 2);
 	sa1100_register_uart(2, 1);
+#endif
+
+	/* set some GPDR bits here while it's safe */
+	GPDR |= GPIO_CF_RESET;
+#ifdef CONFIG_SA1100_CERF_CPLD
+	GPDR |= GPIO_PWR_SHUTDOWN;
 #endif
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/cpu-sa1100.c linux/arch/arm/mach-sa1100/cpu-sa1100.c
--- linux.orig/arch/arm/mach-sa1100/cpu-sa1100.c	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/mach-sa1100/cpu-sa1100.c	Tue May 28 22:39:15 2002
@@ -90,7 +90,8 @@
 
 #include <asm/hardware.h>
 
-
+extern unsigned int sa11x0_freq_to_ppcr(unsigned int khz);
+extern unsigned int sa11x0_validatespeed(unsigned int khz);
 
 
 typedef struct {
@@ -219,14 +220,22 @@
 };
 
 
-
+static void sa1100_setspeed(unsigned int khz)
+{
+	PPCR = sa11x0_freq_to_ppcr(khz);
+}
 
 static int __init sa1100_dram_init(void)
 {
-	return cpufreq_register_notifier(&sa1100_dram_block);
-}
+	int ret = -ENODEV;
 
+	if ((processor_id & CPU_SA1100_MASK) == CPU_SA1100_ID) {
+		ret = cpufreq_register_notifier(&sa1100_dram_block);
 
+		cpufreq_setfunctions(sa11x0_validatespeed, sa1100_setspeed);
+	}
 
+	return ret;
+}
 
 __initcall(sa1100_dram_init);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/cpu-sa1110.c linux/arch/arm/mach-sa1100/cpu-sa1110.c
--- linux.orig/arch/arm/mach-sa1100/cpu-sa1110.c	Thu Oct 11 16:04:57 2001
+++ linux/arch/arm/mach-sa1100/cpu-sa1110.c	Tue May 28 22:39:13 2002
@@ -3,7 +3,7 @@
  *
  *  Copyright (C) 2001 Russell King
  *
- *  $Id: cpu-sa1110.c,v 1.5 2001/09/10 13:25:58 rmk Exp $
+ *  $Id: cpu-sa1110.c,v 1.6 2001/10/22 11:53:47 rmk Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -29,14 +29,8 @@
 
 #undef DEBUG
 
-extern u_int processor_id;
-
-#define CPU_REVISION	(processor_id & 15)
-#define CPU_SA1110_A0	(0)
-#define CPU_SA1110_B0	(4)
-#define CPU_SA1110_B1	(5)
-#define CPU_SA1110_B2	(6)
-#define CPU_SA1110_B4	(8)
+extern unsigned int sa11x0_freq_to_ppcr(unsigned int khz);
+extern unsigned int sa11x0_validatespeed(unsigned int khz);
 
 struct sdram_params {
 	u_char  rows;		/* bits				 */
@@ -48,6 +42,12 @@
 	u_short refresh;	/* refresh time for array (us)	 */
 };
 
+struct sdram_info {
+	u_int	mdcnfg;
+	u_int	mdrefr;
+	u_int	mdcas[3];
+};
+
 static struct sdram_params tc59sm716_cl2_params __initdata = {
 	rows:		    12,
 	tck:		    10,
@@ -68,6 +68,16 @@
 	cas_latency:	     3,
 };
 
+static struct sdram_params samsung_k4s641632d_tc75 __initdata = {
+	rows:		    14,
+	tck:		     9,
+	trcd:		    27,
+	trp:		    20,
+	twr:		     9,
+	refresh:	 64000,
+	cas_latency:	     3,
+};
+
 static struct sdram_params sdram_params;
 
 /*
@@ -95,10 +105,11 @@
 	mdcas[1]  = mdcas[2] = 0x55555555 << (shift & 1);
 }
 
-static void sdram_update_timing(u_int cpu_khz, struct sdram_params *sdram)
+static void
+sdram_calculate_timing(struct sdram_info *sd, u_int cpu_khz,
+		       struct sdram_params *sdram)
 {
-	u_int mdcnfg, mdrefr, mdcas[3], mem_khz, sd_khz, trp, twr;
-	unsigned long flags;
+	u_int mem_khz, sd_khz, trp, twr;
 
 	mem_khz = cpu_khz / 2;
 	sd_khz = mem_khz;
@@ -114,7 +125,7 @@
 	    (CPU_REVISION < CPU_SA1110_B2 && sd_khz < 62000))
 		sd_khz /= 2;
 
-	mdcnfg = MDCNFG & 0x007f007f;
+	sd->mdcnfg = MDCNFG & 0x007f007f;
 
 	twr = ns_to_cycles(sdram->twr, mem_khz);
 
@@ -123,53 +134,26 @@
 	if (trp < 1)
 		trp = 1;
 
-	mdcnfg |= trp << 8;
-	mdcnfg |= trp << 24;
-	mdcnfg |= sdram->cas_latency << 12;
-	mdcnfg |= sdram->cas_latency << 28;
-	mdcnfg |= twr << 14;
-	mdcnfg |= twr << 30;
+	sd->mdcnfg |= trp << 8;
+	sd->mdcnfg |= trp << 24;
+	sd->mdcnfg |= sdram->cas_latency << 12;
+	sd->mdcnfg |= sdram->cas_latency << 28;
+	sd->mdcnfg |= twr << 14;
+	sd->mdcnfg |= twr << 30;
 
-	mdrefr = MDREFR & 0xffbffff0;
-	mdrefr |= 7;
+	sd->mdrefr = MDREFR & 0xffbffff0;
+	sd->mdrefr |= 7;
 
 	if (sd_khz != mem_khz)
-		mdrefr |= MDREFR_K1DB2;
+		sd->mdrefr |= MDREFR_K1DB2;
 
 	/* initial number of '1's in MDCAS + 1 */
-	set_mdcas(mdcas, sd_khz >= 62000, ns_to_cycles(sdram->trcd, mem_khz));
+	set_mdcas(sd->mdcas, sd_khz >= 62000, ns_to_cycles(sdram->trcd, mem_khz));
 
 #ifdef DEBUG
-	mdelay(250);
 	printk("MDCNFG: %08x MDREFR: %08x MDCAS0: %08x MDCAS1: %08x MDCAS2: %08x\n",
-		mdcnfg, mdrefr, mdcas[0], mdcas[1], mdcas[2]);
+		sd->mdcnfg, sd->mdrefr, sd->mdcas[0], sd->mdcas[1], sd->mdcas[2]);
 #endif
-
-	/*
-	 * Reprogram the DRAM timings with interrupts disabled, and
-	 * ensure that we are doing this within a complete cache line.
-	 * This means that we won't access SDRAM for the duration of
-	 * the programming.
-	 */
-	local_irq_save(flags);
-	asm("mcr p15, 0, %0, c10, c4" : : "r" (0));
-	udelay(10);
-	__asm__("
-		b	1f
-		.align	5
-1:		str	%3, [%1, #28]		@ MDREFR
-		str	%4, [%1, #4]		@ MDCAS0
-		str	%5, [%1, #8]		@ MDCAS1
-		str	%6, [%1, #12]		@ MDCAS2
-		str	%2, [%1, #0]		@ MDCNFG
-		ldr	%0, [%1, #0]
-		nop
-		nop"
-		: "=&r" (mdcnfg)
-		: "r" (io_p2v(_MDCNFG)),
-		  "0" (mdcnfg), "r" (mdrefr),
-		  "r" (mdcas[0]), "r" (mdcas[1]), "r" (mdcas[2]));
-	local_irq_restore(flags);
 }
 
 /*
@@ -203,65 +187,92 @@
 	sdram_set_refresh(dri);
 }
 
-static int
-sdram_notifier(struct notifier_block *nb, unsigned long val, void *data)
+/*
+ * Ok, set the CPU frequency.  Since we've done the validation
+ * above, we can match for an exact frequency.  If we don't find
+ * an exact match, we will to set the lowest frequency to be safe.
+ */
+static void sa1110_setspeed(unsigned int khz)
 {
-	struct cpufreq_info *ci = data;
 	struct sdram_params *sdram = &sdram_params;
+	struct sdram_info sd;
+	unsigned long flags;
+	unsigned int ppcr, unused;
 
-	/* were we initialised? */
-	if (sdram->cas_latency == 0) {
-		struct cpufreq_minmax *m = data;
-		m->min_freq = m->max_freq = m->cur_freq;
-		return 0;
-	}
+	ppcr = sa11x0_freq_to_ppcr(khz);
+	sdram_calculate_timing(&sd, khz, sdram);
 
-	switch (val) {
-	case CPUFREQ_MINMAX:
-		/*
-		 * until we work out why the assabet
-		 * crashes below 147.5MHz...
-		 */
-		cpufreq_updateminmax(data, 147500, -1);
-		break;
-
-	case CPUFREQ_PRECHANGE:
-		/*
-		 * The clock could be going away for some time.
-		 * Set the SDRAMs to refresh rapidly (every 64
-		 * memory clock cycles).  To get through the
-		 * whole array, we need to wait 262144 mclk cycles.
-		 * We wait 20ms to be safe.
-		 */
-		sdram_set_refresh(2);
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(20 * HZ / 1000);
-
-		if (ci->old_freq < ci->new_freq)
-			sdram_update_timing(ci->new_freq, sdram);
-		break;
-
-	case CPUFREQ_POSTCHANGE:
-		if (ci->old_freq > ci->new_freq)
-			sdram_update_timing(ci->new_freq, sdram);
-		sdram_update_refresh(ci->new_freq, sdram);
-		break;
+#if 0
+	/*
+	 * These values are wrong according to the SA1110 documentation
+	 * and errata, but they seem to work.  Need to get a storage
+	 * scope on to the SDRAM signals to work out why.
+	 */
+	if (khz < 147500) {
+		sd.mdrefr |= MDREFR_K1DB2;
+		sd.mdcas[0] = 0xaaaaaa7f;
+	} else {
+		sd.mdrefr &= ~MDREFR_K1DB2;
+		sd.mdcas[0] = 0xaaaaaa9f;
 	}
-	return 0;
-}
+	sd.mdcas[1] = 0xaaaaaaaa;
+	sd.mdcas[2] = 0xaaaaaaaa;
+#endif
+	/*
+	 * The clock could be going away for some time.  Set the SDRAMs
+	 * to refresh rapidly (every 64 memory clock cycles).  To get
+	 * through the whole array, we need to wait 262144 mclk cycles.
+	 * We wait 20ms to be safe.
+	 */
+	sdram_set_refresh(2);
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	schedule_timeout(20 * HZ / 1000);
 
-static struct notifier_block sa1110_clkchg_block = {
-	notifier_call:	sdram_notifier,
-};
+	/*
+	 * Reprogram the DRAM timings with interrupts disabled, and
+	 * ensure that we are doing this within a complete cache line.
+	 * This means that we won't access SDRAM for the duration of
+	 * the programming.
+	 */
+	local_irq_save(flags);
+	asm("mcr p15, 0, %0, c10, c4" : : "r" (0));
+	udelay(10);
+	__asm__ __volatile__("
+		b	2f
+		.align	5
+1:		str	%3, [%1, #0]		@ MDCNFG
+		str	%4, [%1, #28]		@ MDREFR
+		str	%5, [%1, #4]		@ MDCAS0
+		str	%6, [%1, #8]		@ MDCAS1
+		str	%7, [%1, #12]		@ MDCAS2
+		str	%8, [%2, #0]		@ PPCR
+		ldr	%0, [%1, #0]
+		b	3f
+2:		b	1b
+3:		nop
+		nop"
+		: "=&r" (unused)
+		: "r" (&MDCNFG), "r" (&PPCR), "0" (sd.mdcnfg),
+		  "r" (sd.mdrefr), "r" (sd.mdcas[0]),
+		  "r" (sd.mdcas[1]), "r" (sd.mdcas[2]), "r" (ppcr));
+	local_irq_restore(flags);
 
-static int __init sa1110_sdram_init(void)
+	/*
+	 * Now, return the SDRAM refresh back to normal.
+	 */
+	sdram_update_refresh(khz, sdram);
+}
+
+static int __init sa1110_clk_init(void)
 {
 	struct sdram_params *sdram = NULL;
-	unsigned int cur_freq = cpufreq_get(smp_processor_id());
 
 	if (machine_is_assabet())
 		sdram = &tc59sm716_cl3_params;
 
+	if (machine_is_pt_system3())
+		sdram = &samsung_k4s641632d_tc75;
+
 	if (sdram) {
 		printk(KERN_DEBUG "SDRAM: tck: %d trcd: %d trp: %d"
 			" twr: %d refresh: %d cas_latency: %d\n",
@@ -270,11 +281,11 @@
 
 		memcpy(&sdram_params, sdram, sizeof(sdram_params));
 
-		sdram_update_timing(cur_freq, &sdram_params);
-		sdram_update_refresh(cur_freq, &sdram_params);
+		sa1110_setspeed(cpufreq_get(0));
+		cpufreq_setfunctions(sa11x0_validatespeed, sa1110_setspeed);
 	}
 
-	return cpufreq_register_notifier(&sa1110_clkchg_block);
+	return 0;
 }
 
-__initcall(sa1110_sdram_init);
+__initcall(sa1110_clk_init);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/dma-sa1100.c linux/arch/arm/mach-sa1100/dma-sa1100.c
--- linux.orig/arch/arm/mach-sa1100/dma-sa1100.c	Thu Oct 25 20:53:46 2001
+++ linux/arch/arm/mach-sa1100/dma-sa1100.c	Tue May 28 22:39:18 2002
@@ -147,6 +147,19 @@
 		}
 
 		/*
+		 * This improves latency if there are some active spinning
+		 * buffers.  We kill them altogether.
+		 */
+		if (dma->spin_ref > 0) {
+			if (channel_is_sa1111_sac(dma - dma_chan))
+				sa1111_reset_sac_dma(dma - dma_chan);
+			else
+				dma->regs->ClrDCSR =
+				    DCSR_STRTA|DCSR_STRTB|DCSR_DONEA|DCSR_DONEB;
+			dma->spin_ref = 0;
+		}
+
+		/*
 		 * Let's try to start DMA on the current buffer.
 		 * If DMA is busy then we break here.
 		 */
@@ -188,8 +201,7 @@
 			 */
 			DPRINTK("IRQ: buf done\n");
 			dma->curr = buf->next;
-			if (dma->curr == NULL)
-				dma->spin_ref = -dma->spin_ref;
+			dma->spin_ref = -dma->spin_ref;
 			if (dma->head == buf)
 				dma->head = NULL;
 			if (dma->callback) {
@@ -468,7 +480,6 @@
 		int flags;
 		save_flags_cli(flags);
 		dma->stopped = 0;
-		dma->spin_ref = 0;
 		process_dma(dma);
 		restore_flags(flags);
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/dma-sa1111.c linux/arch/arm/mach-sa1100/dma-sa1111.c
--- linux.orig/arch/arm/mach-sa1100/dma-sa1111.c	Thu Oct 25 20:53:46 2001
+++ linux/arch/arm/mach-sa1100/dma-sa1111.c	Tue May 28 22:39:17 2002
@@ -22,6 +22,7 @@
 #include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/dma.h>
+#include <asm/hardware/sa1111.h>
 
 // #define DEBUG
 #ifdef DEBUG
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/empeg.c linux/arch/arm/mach-sa1100/empeg.c
--- linux.orig/arch/arm/mach-sa1100/empeg.c	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/mach-sa1100/empeg.c	Tue May 28 22:39:17 2002
@@ -31,7 +31,7 @@
 
 static struct map_desc empeg_io_desc[] __initdata = {
  /* virtual     physical    length      domain     r  w  c  b */
-  { EMPEG_FLASHBASE, 0x00000000, 0x00200000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash */
+  { EMPEG_FLASHBASE, 0x00000000, 0x00200000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash */
   LAST_DESC
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/flexanet.c linux/arch/arm/mach-sa1100/flexanet.c
--- linux.orig/arch/arm/mach-sa1100/flexanet.c	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/mach-sa1100/flexanet.c	Tue May 28 22:39:25 2002
@@ -9,8 +9,6 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -27,22 +25,140 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/serial_sa1100.h>
+#include <linux/serial_core.h>
 
 #include "generic.h"
 
 
-unsigned long BCR_value         = BCR_POWERUP;
-unsigned long flexanet_GUI_type = 0x0000000F;
+unsigned long flexanet_BCR = FHH_BCR_POWERUP;
+
+EXPORT_SYMBOL(flexanet_BCR);
+
+/* physical addresses */
+#define _RCNR        0x90010004
+#define _GPLR        0x90040000
+#define _Ser4SSCR0   0x80070060
+
+/*
+ * Get the modem-control register of the UARTs
+ *
+ */
+static int flexanet_get_mctrl(struct uart_port *port)
+{
+	int            stat = 0;
+	unsigned long  bsr;
+
+	/* only DSR and CTS are implemented in UART1 & 3 */
+	if (port->membase == (void *)&Ser1UTCR0)
+	{
+		bsr = FHH_BSR;
+
+		if ((bsr & FHH_BSR_DSR1) != 0)
+			stat |= TIOCM_DSR;
+		if ((bsr & FHH_BSR_CTS1) != 0)
+			stat |= TIOCM_CTS;
+	}
+	else if (port->membase == (void *)&Ser3UTCR0)
+	{
+		bsr = FHH_BSR;
+
+		if ((bsr & FHH_BSR_DSR3) != 0)
+			stat |= TIOCM_DSR;
+		if ((bsr & FHH_BSR_CTS3) != 0)
+			stat |= TIOCM_CTS;
+	}
+
+	return stat;
+}
+
+/*
+ * Set the modem-control register of the UARTs
+ *
+ */
+static void flexanet_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+	unsigned long	flags;
 
-EXPORT_SYMBOL(BCR_value);
-EXPORT_SYMBOL(flexanet_GUI_type);
+	/* only the RTS signal is implemented in UART1 & 3 */
+	if (port->membase == (void *)&Ser1UTCR0)
+	{
+		local_irq_save(flags);
+
+		if (mctrl & TIOCM_RTS)
+			flexanet_BCR |= FHH_BCR_RTS1;
+		else
+			flexanet_BCR &= ~FHH_BCR_RTS1;
+
+		FHH_BCR = flexanet_BCR;
+		local_irq_restore(flags);
+	}
+	else if (port->membase == (void *)&Ser3UTCR0)
+	{
+		local_irq_save(flags);
+
+		if (mctrl & TIOCM_RTS)
+			flexanet_BCR |= FHH_BCR_RTS3;
+		else
+			flexanet_BCR &= ~FHH_BCR_RTS3;
+
+		FHH_BCR = flexanet_BCR;
+		local_irq_restore(flags);
+	}
+}
+
+/*
+ * machine-specific serial port functions
+ *
+ * get_mctrl : set state of modem control lines
+ * set_mctrl : set the modem control lines
+ * pm        : power-management. Turn device on/off.
+ *
+ */
+static struct sa1100_port_fns	flexanet_port_fns __initdata =
+{
+	set_mctrl : flexanet_set_mctrl,
+	get_mctrl : flexanet_get_mctrl,
+	pm        : NULL,
+};
+
+
+/*
+ * Initialization and serial port mapping
+ *
+ */
+
+static int flexanet_serial_init(void)
+{
+	/* register low-level functions */
+	sa1100_register_uart_fns(&flexanet_port_fns);
+
+	/* UART port number mapping */
+	sa1100_register_uart(0, 1); /* RS232 */
+	sa1100_register_uart(1, 3); /* Radio */
+
+	/* Select UART function in Serial port 1 */
+	Ser1SDCR0 |= SDCR0_UART;
+
+	return 0;
+}
+
+
+static int __init flexanet_init(void)
+{
+	return 0;
+}
+
+__initcall(flexanet_init);
 
-static unsigned long probe_gui_board (void);
 
 static void __init
 fixup_flexanet(struct machine_desc *desc, struct param_struct *params,
 	      char **cmdline, struct meminfo *mi)
 {
+	int				status;
+	unsigned long	now;
+
+
 	/* fixed RAM size, by now (64MB) */
 	SET_BANK( 0, 0xc0000000, 64*1024*1024 );
 	mi->nr_banks = 1;
@@ -56,8 +172,11 @@
 
 static struct map_desc flexanet_io_desc[] __initdata = {
  /* virtual     physical    length      domain     r  w  c  b */
-  { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */
-  { 0xf0000000, 0x10000000, 0x00001000, DOMAIN_IO, 1, 1, 0, 0 }, /* Board Control Register */
+  { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 0 */
+  { 0xf0000000, 0x10000000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, /* Board Control Register */
+  { 0xf1000000, 0x18000000, 0x01000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Ethernet controller */
+  { 0xD0000000, 0x40000000, 0x01000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Instrument boards */
+  { 0xD8000000, 0x48000000, 0x01000000, DOMAIN_IO, 0, 1, 0, 0 }, /* External peripherals */
   LAST_DESC
 };
 
@@ -65,9 +184,27 @@
 {
 	sa1100_map_io();
 	iotable_init(flexanet_io_desc);
+	flexanet_serial_init();
 
-	sa1100_register_uart(0, 1);
-	Ser1SDCR0 |= SDCR0_UART;
+	/* wakeup source is GPIO-0 only */
+	PWER = PWER_GPIO0;
+
+	/* GPIOs set to zero during sleep */
+	PGSR = 0;
+
+	/*
+	 * stop the 3.68 MHz oscillator and float control busses
+	 * during sleep, since peripherals are powered off.
+	 */
+	PCFR = PCFR_OPDE | PCFR_FP | PCFR_FS;
+
+	/* deassert the GUI reset */
+	FLEXANET_BCR_set(FHH_BCR_GUI_NRST);
+
+	/*
+	 * Set IRQ edges
+	 */
+	set_GPIO_IRQ_edge(GPIO_GUI_IRQ, GPIO_RISING_EDGE);
 }
 
 
@@ -78,3 +215,4 @@
 	MAPIO(flexanet_map_io)
 	INITIRQ(sa1100_init_irq)
 MACHINE_END
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/freebird.c linux/arch/arm/mach-sa1100/freebird.c
--- linux.orig/arch/arm/mach-sa1100/freebird.c	Thu Oct 25 20:53:46 2001
+++ linux/arch/arm/mach-sa1100/freebird.c	Tue May 28 22:39:18 2002
@@ -37,9 +37,9 @@
 
 static struct map_desc freebird_io_desc[] __initdata = {
  /* virtual     physical    length      domain     r  w  c  b */
-  { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */
-  { 0xf0000000, 0x12000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* Board Control Register */
-  { 0xf2000000, 0x19000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0},
+  { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 0 */
+  { 0xf0000000, 0x12000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* Board Control Register */
+  { 0xf2000000, 0x19000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0},
    LAST_DESC
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/frodo.c linux/arch/arm/mach-sa1100/frodo.c
--- linux.orig/arch/arm/mach-sa1100/frodo.c	Thu Jan  1 00:00:00 1970
+++ linux/arch/arm/mach-sa1100/frodo.c	Tue May 28 22:39:25 2002
@@ -0,0 +1,61 @@
+
+/*
+ * linux/arch/arm/mach-sa1100/frodo.c
+ *
+ * Author: Abraham van der Merwe <abraham@2d3d.co.za>
+ *
+ * This file contains the 2d3D, Inc. SA-1110 Development Board tweaks.
+ *
+ * This source code is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * History:
+ *
+ *   2002/01/31   Initial version
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/tty.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/serial_sa1100.h>
+
+#include "generic.h"
+
+static struct map_desc frodo_io_desc[] __initdata =
+{
+  /* virtual     physical    length      domain     r  w  c  b */
+   { 0xe8000000, 0x00000000, 0x04000000, DOMAIN_IO, 1, 1, 0, 0 },	/* flash memory */
+   { 0xf0000000, 0x40000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 },	/* 16-bit on-board devices (including CPLDs) */
+   { 0xf1000000, 0x18000000, 0x04000000, DOMAIN_IO, 1, 1, 0, 0 },	/* 32-bit daughter card */
+   LAST_DESC
+};
+
+static void __init frodo_map_io (void)
+{
+   sa1100_map_io ();
+   iotable_init (frodo_io_desc);
+
+   sa1100_register_uart (0,2);	/* UART2 (serial console) */
+   sa1100_register_uart (1,1);	/* UART1 (big kahuna flow control serial port) */
+
+   /*
+	* Set SUS bit in SDCR0 so serial port 1 acts as a UART.
+	* See Intel SA-1110 Developers Manual Section 11.9.2.1 (GPCLK/UART Select)
+	*/
+   Ser1SDCR0 |= SDCR0_SUS;
+}
+
+MACHINE_START (FRODO,"2d3D, Inc. SA-1110 Development Board")
+	BOOT_MEM (0xc0000000,0x80000000,0xf8000000)
+	BOOT_PARAMS (0xc0000100)
+	MAPIO (frodo_map_io)
+	INITIRQ (sa1100_init_irq)
+MACHINE_END
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/generic.c linux/arch/arm/mach-sa1100/generic.c
--- linux.orig/arch/arm/mach-sa1100/generic.c	Thu Oct 11 16:04:57 2001
+++ linux/arch/arm/mach-sa1100/generic.c	Tue May 28 22:39:21 2002
@@ -56,20 +56,13 @@
 /*
  * Return the current CPU clock frequency in units of 100kHz
  */
-unsigned short get_cclk_frequency(void)
+static inline unsigned short get_cclk_frequency(void)
 {
 	return cclk_frequency_100khz[PPCR & 0xf];
 }
 
-EXPORT_SYMBOL(get_cclk_frequency);
-
 #ifdef CONFIG_CPU_FREQ
-
-/*
- * Validate the speed in khz.  If we can't generate the precise
- * frequency requested, round it down (to be on the safe side).
- */
-unsigned int sa1100_validatespeed(unsigned int khz)
+unsigned int sa11x0_freq_to_ppcr(unsigned int khz)
 {
 	int i;
 
@@ -79,35 +72,34 @@
 		if (cclk_frequency_100khz[i] <= khz)
 			break;
 
-	return cclk_frequency_100khz[i] * 100;
+	return i;
 }
 
 /*
- * Ok, set the CPU frequency.  Since we've done the validation
- * above, we can match for an exact frequency.  If we don't find
- * an exact match, we will to set the lowest frequency to be safe.
+ * Validate the speed in khz.  If we can't generate the precise
+ * frequency requested, round it down (to be on the safe side).
  */
-void sa1100_setspeed(unsigned int khz)
+unsigned int sa11x0_validatespeed(unsigned int khz)
 {
-	int i;
-
-	khz /= 100;
-
-	for (i = NR_FREQS - 1; i > 0; i--)
-		if (cclk_frequency_100khz[i] == khz)
-			break;
-//printk("setting ppcr to %d\n", i);
-	PPCR = i;
+	return cclk_frequency_100khz[sa11x0_freq_to_ppcr(khz)] * 100;
 }
 
-static int __init sa1100_init_clock(void)
+static int __init sa11x0_init_clock(void)
 {
-	cpufreq_init(get_cclk_frequency() * 100);
-	cpufreq_setfunctions(sa1100_validatespeed, sa1100_setspeed);
+	cpufreq_init(cclk_frequency_100khz[PPCR & 0xf] * 100);
 	return 0;
 }
 
-__initcall(sa1100_init_clock);
+__initcall(sa11x0_init_clock);
+#else
+/*
+ * We still need to provide this so building without cpufreq works.
+ */ 
+unsigned int cpufreq_get(int cpu)
+{
+	return cclk_frequency_100khz[PPCR & 0xf] * 100;
+}
+EXPORT_SYMBOL(cpufreq_get);
 #endif
 
 /*
@@ -130,13 +122,13 @@
 	PMCR = PMCR_SF;
 }
 
-static int __init sa1100_set_poweroff(void)
+static int __init sa1100_init(void)
 {
 	pm_power_off = sa1100_power_off;
 	return 0;
 }
 
-__initcall(sa1100_set_poweroff);
+__initcall(sa1100_init);
 
 
 /*
@@ -149,7 +141,8 @@
  * 0xf0000000-0xf3ffffff:	miscellaneous stuff (CPLDs, etc.)
  * 0xf4000000-0xf4ffffff:	SA-1111
  * 0xf5000000-0xf5ffffff:	reserved (used by cache flushing area)
- * 0xf6000000-0xffffffff:	reserved (internal SA1100 IO defined above)
+ * 0xf6000000-0xfffeffff:	reserved (internal SA1100 IO defined above)
+ * 0xffff0000-0xffff0fff:	SA1100 exception vectors
  *
  * Below 0xe8000000 is reserved for vm allocation.
  *
@@ -159,8 +152,8 @@
 
 static struct map_desc standard_io_desc[] __initdata = {
  /* virtual     physical    length      domain     r  w  c  b */
-  { 0xf6000000, 0x20000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* PCMCIA0 IO */
-  { 0xf7000000, 0x30000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* PCMCIA1 IO */
+  { 0xf6000000, 0x20000000, 0x01000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA0 IO */
+  { 0xf7000000, 0x30000000, 0x01000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA1 IO */
   { 0xf8000000, 0x80000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCM */
   { 0xfa000000, 0x90000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* SCM */
   { 0xfc000000, 0xa0000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* MER */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/graphicsclient.c linux/arch/arm/mach-sa1100/graphicsclient.c
--- linux.orig/arch/arm/mach-sa1100/graphicsclient.c	Thu Oct 25 20:53:46 2001
+++ linux/arch/arm/mach-sa1100/graphicsclient.c	Tue May 28 22:39:31 2002
@@ -113,7 +113,6 @@
 		irq_desc[irq].mask	= ADS_mask_irq1;
 		irq_desc[irq].unmask	= ADS_unmask_irq1;
 	}
-	GPDR &= ~GPIO_GPIO0;
 	set_GPIO_IRQ_edge(GPIO_GPIO0, GPIO_FALLING_EDGE);
 	setup_arm_irq( IRQ_GPIO0, &ADS_ext_irq );
 }
@@ -138,7 +137,7 @@
 
 static struct map_desc graphicsclient_io_desc[] __initdata = {
  /* virtual     physical    length      domain     r  w  c  b */
-  { 0xe8000000, 0x08000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */
+  { 0xe8000000, 0x08000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 1 */
   { 0xf0000000, 0x10000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* CPLD */
   { 0xf1000000, 0x18000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* CAN */
   LAST_DESC
@@ -193,12 +192,8 @@
 	if (port->mapbase == _Ser1UTCR0) {
 		Ser1SDCR0 |= SDCR0_UART;
 		/* Set RTS Output */
-		GPDR |= GPIO_GC_UART0_RTS;
 		GPSR  = GPIO_GC_UART0_RTS;
 
-		/* Set CTS Input */
-		GPDR &= ~GPIO_GC_UART0_CTS;
-
 		gc_uart_ctrl_data[0].cts_prev_state = 0;
 		gc_uart_ctrl_data[0].info = info;
 		gc_uart_ctrl_data[0].port = port;
@@ -210,12 +205,8 @@
 	} else if (port->mapbase == _Ser2UTCR0) {
 		Ser2UTCR4 = Ser2HSCR0 = 0;
 		/* Set RTS Output */
-		GPDR |= GPIO_GC_UART1_RTS;
 		GPSR  = GPIO_GC_UART1_RTS;
 
-		/* Set CTS Input */
-		GPDR &= ~GPIO_GC_UART1_RTS;
-
 		gc_uart_ctrl_data[1].cts_prev_state = 0;
 		gc_uart_ctrl_data[1].info = info;
 		gc_uart_ctrl_data[1].port = port;
@@ -226,12 +217,8 @@
 							&gc_uart_ctrl_data[1]);
 	} else if (port->mapbase == _Ser3UTCR0) {
 		/* Set RTS Output */
-		GPDR |= GPIO_GC_UART2_RTS;
 		GPSR =	GPIO_GC_UART2_RTS;
 
-		/* Set CTS Input */
-		GPDR &= ~GPIO_GC_UART2_RTS;
-
 		gc_uart_ctrl_data[2].cts_prev_state = 0;
 		gc_uart_ctrl_data[2].info = info;
 		gc_uart_ctrl_data[2].port = port;
@@ -258,9 +245,9 @@
 	return 0;
 }
 
-static int graphicsclient_get_mctrl(struct uart_port *port)
+static u_int graphicsclient_get_mctrl(struct uart_port *port)
 {
-	int result = TIOCM_CD | TIOCM_DSR;
+	u_int result = TIOCM_CD | TIOCM_DSR;
 
 	if (port->mapbase == _Ser1UTCR0) {
 		if (!(GPLR & GPIO_GC_UART0_CTS))
@@ -326,6 +313,8 @@
 	sa1100_register_uart(0, 3);
 	sa1100_register_uart(1, 1);
 	sa1100_register_uart(2, 2);
+	GPDR |= GPIO_GC_UART0_RTS | GPIO_GC_UART1_RTS | GPIO_GC_UART2_RTS;
+	GPDR &= ~(GPIO_GC_UART0_CTS | GPIO_GC_UART1_RTS | GPIO_GC_UART2_RTS);
 }
 
 MACHINE_START(GRAPHICSCLIENT, "ADS GraphicsClient")
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/graphicsmaster.c linux/arch/arm/mach-sa1100/graphicsmaster.c
--- linux.orig/arch/arm/mach-sa1100/graphicsmaster.c	Thu Oct 25 20:53:46 2001
+++ linux/arch/arm/mach-sa1100/graphicsmaster.c	Tue May 28 22:39:25 2002
@@ -43,7 +43,7 @@
 	/*
 	 * Probe for SA1111.
 	 */
-	ret = sa1111_probe();
+	ret = sa1111_probe(ADS_SA1111_BASE);
 	if (ret < 0)
 		return ret;
 
@@ -174,7 +174,6 @@
 		irq_desc[irq].mask	= ADS_mask_irq1;
 		irq_desc[irq].unmask	= ADS_unmask_irq1;
 	}
-	GPDR &= ~GPIO_GPIO0;
 	set_GPIO_IRQ_edge(GPIO_GPIO0, GPIO_FALLING_EDGE);
 	setup_arm_irq( IRQ_GPIO0, &ADS_ext_irq );
 }
@@ -200,10 +199,10 @@
 
 static struct map_desc graphicsmaster_io_desc[] __initdata = {
  /* virtual     physical    length      domain     r  w  c  b */
-  { 0xe8000000, 0x08000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */
-  { 0xf0000000, 0x10000000, 0x00400000, DOMAIN_IO, 1, 1, 0, 0 }, /* CPLD */
-  { 0xf1000000, 0x40000000, 0x00400000, DOMAIN_IO, 1, 1, 0, 0 }, /* CAN */
-  { 0xf4000000, 0x18000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* SA-1111 */
+  { 0xe8000000, 0x08000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 1 */
+  { 0xf0000000, 0x10000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* CPLD */
+  { 0xf1000000, 0x40000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* CAN */
+  { 0xf4000000, 0x18000000, 0x00800000, DOMAIN_IO, 0, 1, 0, 0 }, /* SA-1111 */
   LAST_DESC
 };
 
@@ -215,31 +214,22 @@
 		Ser1SDCR0 |= SDCR0_UART;
 		/* Set RTS Output */
 		GPSR = GPIO_GPIO15;
-		GPDR |= GPIO_GPIO15;
-		/* Set CTS Input */
-		GPDR &= ~GPIO_GPIO14;
 	}
 	else if (port->mapbase == _Ser2UTCR0) {
 		Ser2UTCR4 = Ser2HSCR0 = 0;
 		/* Set RTS Output */
 		GPSR = GPIO_GPIO17;
-		GPDR |= GPIO_GPIO17;
-		/* Set CTS Input */
-		GPDR &= ~GPIO_GPIO16;
 	}
 	else if (port->mapbase == _Ser3UTCR0) {
 	        /* Set RTS Output */
 		GPSR = GPIO_GPIO19;
-		GPDR |= GPIO_GPIO19;
-		/* Set CTS Input */
-		GPDR &= ~GPIO_GPIO18;
 	}
 	return ret;
 }
 
-static int graphicsmaster_get_mctrl(struct uart_port *port)
+static u_int graphicsmaster_get_mctrl(struct uart_port *port)
 {
-	int result = TIOCM_CD | TIOCM_DSR;
+	u_int result = TIOCM_CD | TIOCM_DSR;
 
 	if (port->mapbase == _Ser1UTCR0) {
 		if (!(GPLR & GPIO_GPIO14))
@@ -304,6 +294,10 @@
 	sa1100_register_uart(0, 3);
 	sa1100_register_uart(1, 1);
 	sa1100_register_uart(2, 2);
+
+	/* set GPDR now */
+	GPDR |= GPIO_GPIO15 | GPIO_GPIO17 | GPIO_GPIO19;
+       	GPDR &= ~(GPIO_GPIO14 | GPIO_GPIO16 | GPIO_GPIO18);
 }
 
 MACHINE_START(GRAPHICSMASTER, "ADS GraphicsMaster")
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/h3600.c linux/arch/arm/mach-sa1100/h3600.c
--- linux.orig/arch/arm/mach-sa1100/h3600.c	Thu Oct 25 20:53:46 2001
+++ linux/arch/arm/mach-sa1100/h3600.c	Tue May 28 22:39:19 2002
@@ -1,8 +1,24 @@
 /*
- * linux/arch/arm/mach-sa1100/h3600.c
+ * Hardware definitions for Compaq iPAQ H3xxx Handheld Computers
+ *
+ * Copyright 2000,1 Compaq Computer Corporation.
+ *
+ * Use consistent with the GNU GPL is permitted,
+ * provided that this copyright notice is
+ * preserved in its entirety in all copies and derived works.
+ *
+ * COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
+ * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
+ * FITNESS FOR ANY PARTICULAR PURPOSE.
+ *
+ * Author: Jamey Hicks.
+ *
+ * History:
+ *
+ * 2001-10-??	Andrew Christian   Added support for iPAQ H3800
+ *				   and abstracted EGPIO interface.
+ *
  */
-
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -17,84 +33,338 @@
 #include <asm/mach/map.h>
 #include <asm/mach/serial_sa1100.h>
 #include <linux/serial_core.h>
+#include <asm/arch/h3600_gpio.h>
 
 #include "generic.h"
 
-
 /*
- * Bitsy has extended, write-only memory-mapped GPIO's
+ * H3600 has extended, write-only memory-mapped GPIO's
+ * H3100 has 1/2 extended, write-only GPIO and 1/2 on
+ *	 regular GPIO lines.
+ * H3800 has memory-mapped GPIO through ASIC1 & 2
  */
 
-static int h3600_egpio = EGPIO_H3600_RS232_ON;
+#define H3600_EGPIO	(*(volatile unsigned int *)H3600_EGPIO_VIRT)
+
+static unsigned int h3600_egpio;
+
+/************************* H3100 *************************/
+
+#define H3100_DIRECT_EGPIO (GPIO_H3100_BT_ON	  \
+			  | GPIO_H3100_GPIO3	  \
+			  | GPIO_H3100_QMUTE	  \
+			  | GPIO_H3100_LCD_3V_ON  \
+			  | GPIO_H3100_AUD_ON	  \
+			  | GPIO_H3100_AUD_PWR_ON \
+			  | GPIO_H3100_IR_ON	  \
+			  | GPIO_H3100_IR_FSEL)
+
+static void h3100_init_egpio( void )
+{
+	GPDR |= H3100_DIRECT_EGPIO;
+	GPCR = H3100_DIRECT_EGPIO;   /* Initially all off */
+
+	/* Older bootldrs put GPIO2-9 in alternate mode on the
+	   assumption that they are used for video */
+	GAFR &= ~H3100_DIRECT_EGPIO;
+
+	h3600_egpio = EGPIO_H3600_RS232_ON;
+	H3600_EGPIO = h3600_egpio;
+}
+
+static void h3100_control_egpio( enum ipaq_egpio_type x, int setp )
+{
+	unsigned int egpio = 0;
+	long	     gpio = 0;
+	unsigned long flags;
+
+	switch (x) {
+	case IPAQ_EGPIO_LCD_ON:
+		egpio |= EGPIO_H3600_LCD_ON;
+		gpio  |= GPIO_H3100_LCD_3V_ON;
+		break;
+	case IPAQ_EGPIO_CODEC_NRESET:
+		egpio |= EGPIO_H3600_CODEC_NRESET;
+		break;
+	case IPAQ_EGPIO_AUDIO_ON:
+		gpio |= GPIO_H3100_AUD_PWR_ON
+			| GPIO_H3100_AUD_ON;
+		break;
+	case IPAQ_EGPIO_QMUTE:
+		gpio |= GPIO_H3100_QMUTE;
+		break;
+	case IPAQ_EGPIO_OPT_NVRAM_ON:
+		egpio |= EGPIO_H3600_OPT_NVRAM_ON;
+		break;
+	case IPAQ_EGPIO_OPT_ON:
+		egpio |= EGPIO_H3600_OPT_ON;
+		break;
+	case IPAQ_EGPIO_CARD_RESET:
+		egpio |= EGPIO_H3600_CARD_RESET;
+		break;
+	case IPAQ_EGPIO_OPT_RESET:
+		egpio |= EGPIO_H3600_OPT_RESET;
+		break;
+	case IPAQ_EGPIO_IR_ON:
+		gpio |= GPIO_H3100_IR_ON;
+		break;
+	case IPAQ_EGPIO_IR_FSEL:
+		gpio |= GPIO_H3100_IR_FSEL;
+		break;
+	case IPAQ_EGPIO_RS232_ON:
+		egpio |= EGPIO_H3600_RS232_ON;
+		break;
+	case IPAQ_EGPIO_VPP_ON:
+		egpio |= EGPIO_H3600_VPP_ON;
+		break;
+	}
+
+	local_irq_save(flags);
+	if ( setp ) {
+		h3600_egpio |= egpio;
+		GPSR = gpio;
+	} else {
+		h3600_egpio &= ~egpio;
+		GPCR = gpio;
+	}
+	H3600_EGPIO = h3600_egpio;
+	local_irq_restore(flags);
 
-void init_h3600_egpio(void)
+	/*
+	if ( x != IPAQ_EGPIO_VPP_ON ) {
+		printk(__FUNCTION__ " : type=%d (%s) gpio=0x%x (0x%x) egpio=0x%x (0x%x) setp=%d\n",
+		       x, egpio_names[x], GPLR, gpio, h3600_egpio, egpio, setp );
+	}
+	*/
+}
+
+static unsigned long h3100_read_egpio( void )
 {
-#ifdef CONFIG_IPAQ_H3100
-	int h3100_controls = (GPIO_H3100_BT_ON
-			      | GPIO_H3100_QMUTE
-			      | GPIO_H3100_LCD_3V_ON 
-			      | GPIO_H3100_AUD_ON
-			      | GPIO_H3100_AUD_PWR_ON
-			      | GPIO_H3100_IR_ON
-			      | GPIO_H3100_IR_FSEL);
-	GPDR |= h3100_controls;
-	GPCR = h3100_controls;
-	GAFR = GPIO_SSP_CLK;
-#endif
-}
-
-void clr_h3600_egpio(unsigned long x)
-{
-#ifdef CONFIG_IPAQ_H3100
-	unsigned long gpcr = 0;
-	if (x&EGPIO_H3600_QMUTE)
-		gpcr |= GPIO_H3100_QMUTE;
-	if (x&EGPIO_H3600_LCD_ON)
-		gpcr |= GPIO_H3100_LCD_3V_ON;
-	if (x&EGPIO_H3600_AUD_AMP_ON)
-		gpcr |= GPIO_H3100_AUD_ON;
-	if (x&EGPIO_H3600_AUD_PWR_ON)
-		gpcr |= GPIO_H3100_AUD_PWR_ON;
-	if (x&EGPIO_H3600_IR_ON)
-		gpcr |= GPIO_H3100_IR_ON;
-	if (x&EGPIO_H3600_IR_FSEL)
-		gpcr |= GPIO_H3100_IR_FSEL;
-	GPCR = gpcr;
-#endif
-	h3600_egpio &= ~x;
+	return h3600_egpio;
+}
+
+static struct ipaq_model_ops h3100_model_ops __initdata = {
+	model	     : IPAQ_H3100,
+	generic_name : "3100",
+	initialize   : h3100_init_egpio,
+	control      : h3100_control_egpio,
+	read	     : h3100_read_egpio
+};
+
+
+/************************* H3600 *************************/
+
+static void h3600_init_egpio( void )
+{
+	h3600_egpio = EGPIO_H3600_RS232_ON;
 	H3600_EGPIO = h3600_egpio;
 }
 
-void set_h3600_egpio(unsigned long x)
+static void h3600_control_egpio( enum ipaq_egpio_type x, int setp )
 {
-#ifdef CONFIG_IPAQ_H3100
-	unsigned long gpsr = 0;
-	if (x&EGPIO_H3600_QMUTE)
-		gpsr |= GPIO_H3100_QMUTE;
-	if (x&EGPIO_H3600_LCD_ON)
-		gpsr |= GPIO_H3100_LCD_3V_ON;
-	if (x&EGPIO_H3600_AUD_AMP_ON)
-		gpsr |= GPIO_H3100_AUD_ON;
-	if (x&EGPIO_H3600_AUD_PWR_ON)
-		gpsr |= GPIO_H3100_AUD_PWR_ON;
-	if (x&EGPIO_H3600_IR_ON)
-		gpsr |= GPIO_H3100_IR_ON;
-	if (x&EGPIO_H3600_IR_FSEL)
-		gpsr |= GPIO_H3100_IR_FSEL;
-	GPSR = gpsr;
-#endif
-	h3600_egpio |= x;
+	unsigned int egpio = 0;
+	unsigned long flags;
+
+	switch (x) {
+	case IPAQ_EGPIO_LCD_ON:
+		egpio |= EGPIO_H3600_LCD_ON |
+			 EGPIO_H3600_LCD_PCI |
+			 EGPIO_H3600_LCD_5V_ON |
+			 EGPIO_H3600_LVDD_ON;
+		break;
+	case IPAQ_EGPIO_CODEC_NRESET:
+		egpio |= EGPIO_H3600_CODEC_NRESET;
+		break;
+	case IPAQ_EGPIO_AUDIO_ON:
+		egpio |= EGPIO_H3600_AUD_AMP_ON |
+			EGPIO_H3600_AUD_PWR_ON;
+		break;
+	case IPAQ_EGPIO_QMUTE:
+		egpio |= EGPIO_H3600_QMUTE;
+		break;
+	case IPAQ_EGPIO_OPT_NVRAM_ON:
+		egpio |= EGPIO_H3600_OPT_NVRAM_ON;
+		break;
+	case IPAQ_EGPIO_OPT_ON:
+		egpio |= EGPIO_H3600_OPT_ON;
+		break;
+	case IPAQ_EGPIO_CARD_RESET:
+		egpio |= EGPIO_H3600_CARD_RESET;
+		break;
+	case IPAQ_EGPIO_OPT_RESET:
+		egpio |= EGPIO_H3600_OPT_RESET;
+		break;
+	case IPAQ_EGPIO_IR_ON:
+		egpio |= EGPIO_H3600_IR_ON;
+		break;
+	case IPAQ_EGPIO_IR_FSEL:
+		egpio |= EGPIO_H3600_IR_FSEL;
+		break;
+	case IPAQ_EGPIO_RS232_ON:
+		egpio |= EGPIO_H3600_RS232_ON;
+		break;
+	case IPAQ_EGPIO_VPP_ON:
+		egpio |= EGPIO_H3600_VPP_ON;
+		break;
+	}
+
+	local_irq_save(flags);
+	if ( setp )
+		h3600_egpio |= egpio;
+	else
+		h3600_egpio &= ~egpio;
 	H3600_EGPIO = h3600_egpio;
+	local_irq_restore(flags);
+}
+
+static unsigned long h3600_read_egpio( void )
+{
+	return h3600_egpio;
+}
+
+static struct ipaq_model_ops h3600_model_ops __initdata = {
+	model	     : IPAQ_H3600,
+	generic_name : "3600",
+	initialize   : h3600_init_egpio,
+	control      : h3600_control_egpio,
+	read	     : h3600_read_egpio
+};
+
+/************************* H3800 *************************/
+
+#define ASIC1_OUTPUTS	 0x7fff   /* First 15 bits are used */
+
+static unsigned int h3800_asic1_gpio;
+static unsigned int h3800_asic2_gpio;
+
+static void h3800_init_egpio(void)
+{
+	/* Set up ASIC #1 */
+	H3800_ASIC1_GPIO_Direction    = ASIC1_OUTPUTS;		  /* All outputs */
+	H3800_ASIC1_GPIO_Mask	      = ASIC1_OUTPUTS;		  /* No interrupts */
+	H3800_ASIC1_GPIO_SleepMask    = ASIC1_OUTPUTS;
+	H3800_ASIC1_GPIO_SleepDir     = ASIC1_OUTPUTS;
+	H3800_ASIC1_GPIO_SleepOut     = GPIO_H3800_ASIC1_EAR_ON_N;
+	H3800_ASIC1_GPIO_BattFaultDir = ASIC1_OUTPUTS;
+	H3800_ASIC1_GPIO_BattFaultOut = GPIO_H3800_ASIC1_EAR_ON_N;
+
+	h3800_asic1_gpio = GPIO_H3800_ASIC1_IR_ON_N   /* TODO: Check IR level */
+		| GPIO_H3800_ASIC1_RS232_ON
+		| GPIO_H3800_ASIC1_EAR_ON_N;
+
+	H3800_ASIC1_GPIO_Out = h3800_asic1_gpio;
+
+	/* Set up ASIC #2 */
+	H3800_ASIC2_GPIO_Direction = GPIO_H3800_ASIC2_PEN_IRQ
+		| GPIO_H3800_ASIC2_SD_DETECT
+		| GPIO_H3800_ASIC2_EAR_IN_N
+		| GPIO_H3800_ASIC2_USB_DETECT_N
+		| GPIO_H3800_ASIC2_SD_CON_SLT;
+
+	h3800_asic2_gpio = GPIO_H3800_ASIC2_IN_Y1_N | GPIO_H3800_ASIC2_IN_X1_N;
+	H3800_ASIC2_GPIO_Data	      = h3800_asic2_gpio;
+	H3800_ASIC2_GPIO_BattFaultOut = h3800_asic2_gpio;
+
+	/* TODO : Set sleep states & battery fault states */
+
+	/* Clear VPP Enable */
+	H3800_ASIC1_FlashWP_VPP_ON = 0;
+}
+
+static void h3800_control_egpio( enum ipaq_egpio_type x, int setp )
+{
+	unsigned int set_asic1_egpio = 0;
+	unsigned int clear_asic1_egpio = 0;
+	unsigned long flags;
+
+	switch (x) {
+	case IPAQ_EGPIO_LCD_ON:
+		set_asic1_egpio |= GPIO_H3800_ASIC1_LCD_5V_ON
+			| GPIO_H3800_ASIC1_LCD_ON
+			| GPIO_H3800_ASIC1_LCD_PCI
+			| GPIO_H3800_ASIC1_VGH_ON
+			| GPIO_H3800_ASIC1_VGL_ON;
+		break;
+	case IPAQ_EGPIO_CODEC_NRESET:
+		break;
+	case IPAQ_EGPIO_AUDIO_ON:
+		break;
+	case IPAQ_EGPIO_QMUTE:
+		break;
+	case IPAQ_EGPIO_OPT_NVRAM_ON:
+		break;
+	case IPAQ_EGPIO_OPT_ON:
+		break;
+	case IPAQ_EGPIO_CARD_RESET:
+		break;
+	case IPAQ_EGPIO_OPT_RESET:
+		break;
+	case IPAQ_EGPIO_IR_ON:
+		clear_asic1_egpio |= GPIO_H3800_ASIC1_IR_ON_N;	 /* TODO : This is backwards? */
+		break;
+	case IPAQ_EGPIO_IR_FSEL:
+		break;
+	case IPAQ_EGPIO_RS232_ON:
+		set_asic1_egpio |= GPIO_H3800_ASIC1_RS232_ON;
+		break;
+	case IPAQ_EGPIO_VPP_ON:
+		H3800_ASIC1_FlashWP_VPP_ON = setp;
+		break;
+	}
+
+	local_irq_save(flags);
+	if ( setp ) {
+		h3800_asic1_gpio |= set_asic1_egpio;
+		h3800_asic1_gpio &= ~clear_asic1_egpio;
+	}
+	else {
+		h3800_asic1_gpio &= ~set_asic1_egpio;
+		h3800_asic1_gpio |= clear_asic1_egpio;
+	}
+	H3800_ASIC1_GPIO_Out = h3800_asic1_gpio;
+	local_irq_restore(flags);
 }
 
-EXPORT_SYMBOL(clr_h3600_egpio);
-EXPORT_SYMBOL(set_h3600_egpio);
+static unsigned long h3800_read_egpio( void )
+{
+	return h3800_asic1_gpio | (h3800_asic2_gpio << 16);
+}
+
+static struct ipaq_model_ops h3800_model_ops __initdata = {
+	model	     : IPAQ_H3800,
+	generic_name : "3800",
+	initialize   : h3800_init_egpio,
+	control      : h3800_control_egpio,
+	read	     : h3800_read_egpio
+};
 
 
 /*
- * Low-level UART features.
- *
- * Note that RTS, CTS and DCD are all active low.
+ * Use command line argument to choose between ipaq handheld model numbers
+ */
+
+struct ipaq_model_ops ipaq_model_ops;
+EXPORT_SYMBOL(ipaq_model_ops);
+
+static int __init h3600_init_model_ops(void)
+{
+	if (machine_is_h3xxx()) {
+		if (machine_is_h3100()) {
+			ipaq_model_ops = h3100_model_ops;
+		} else if (machine_is_h3600()) {
+			ipaq_model_ops = h3600_model_ops;
+		} else if (machine_is_h3800()) {
+			ipaq_model_ops = h3800_model_ops;
+		}
+		init_h3600_egpio();
+	}
+	return 0;
+}
+
+__initcall(h3600_init_model_ops);
+
+/*
+ * low-level UART features
  */
 
 static void h3600_uart_set_mctrl(struct uart_port *port, u_int mctrl)
@@ -107,9 +377,9 @@
 	}
 }
 
-static int h3600_uart_get_mctrl(struct uart_port *port)
+static u_int h3600_uart_get_mctrl(struct uart_port *port)
 {
-	int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
+	u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
 
 	if (port->mapbase == _Ser3UTCR0) {
 		int gplr = GPLR;
@@ -139,20 +409,30 @@
 static void h3600_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
 {
 	if (port->mapbase == _Ser2UTCR0) {
-		if (state == 0) {
-			set_h3600_egpio(EGPIO_H3600_IR_ON);
-		} else {
-			clr_h3600_egpio(EGPIO_H3600_IR_ON);
-		}
+		assign_h3600_egpio( IPAQ_EGPIO_IR_ON, !state );
 	} else if (port->mapbase == _Ser3UTCR0) {
-		if (state == 0) {
-			set_h3600_egpio(EGPIO_H3600_RS232_ON);
-		} else {
-			clr_h3600_egpio(EGPIO_H3600_RS232_ON);
-		}
+		assign_h3600_egpio( IPAQ_EGPIO_RS232_ON, !state );
 	}
 }
 
+/*
+ * Enable/Disable wake up events for this serial port.
+ * Obviously, we only support this on the normal COM port.
+ */
+static int h3600_uart_set_wake(struct uart_port *port, u_int enable)
+{
+	int err = -EINVAL;
+
+	if (port->mapbase == _Ser3UTCR0) {
+		if (enable)
+			PWER |= PWER_GPIO23 | PWER_GPIO25 ; /* DCD and CTS */
+		else
+			PWER &= ~(PWER_GPIO23 | PWER_GPIO25); /* DCD and CTS */
+		err = 0;
+	}
+	return err;
+}
+
 static int h3600_uart_open(struct uart_port *port, struct uart_info *info)
 {
 	int ret = 0;
@@ -163,8 +443,6 @@
 		Ser2HSSR0 = HSSR0_EIF | HSSR0_TUR |
 			    HSSR0_RAB | HSSR0_FRE;
 	} else if (port->mapbase == _Ser3UTCR0) {
-		GPDR &= ~(GPIO_H3600_COM_DCD|GPIO_H3600_COM_CTS);
-		GPDR |= GPIO_H3600_COM_RTS;
 		set_GPIO_IRQ_edge(GPIO_H3600_COM_DCD|GPIO_H3600_COM_CTS,
 				  GPIO_BOTH_EDGES);
 
@@ -193,16 +471,17 @@
 	set_mctrl:	h3600_uart_set_mctrl,
 	get_mctrl:	h3600_uart_get_mctrl,
 	pm:		h3600_uart_pm,
+	set_wake:	h3600_uart_set_wake,
 	open:		h3600_uart_open,
 	close:		h3600_uart_close,
 };
 
 static struct map_desc h3600_io_desc[] __initdata = {
- /* virtual     physical    length      domain     r  w  c  b */
-  { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */
-  { 0xf0000000, 0x49000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* EGPIO 0 */
-  { 0xf1000000, 0x10000000, 0x02800000, DOMAIN_IO, 1, 1, 0, 0 }, /* static memory bank 2 */
-  { 0xf3800000, 0x40000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* static memory bank 4 */
+ /* virtual	       physical    length      domain	  r  w	c  b */
+  { 0xe8000000,        0x00000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 0 	 CS#0 */
+  { H3600_EGPIO_VIRT,  0x49000000, 0x01000000, DOMAIN_IO, 0, 1, 0, 0 }, /* EGPIO 0		 CS#5 */
+  { H3600_BANK_2_VIRT, 0x10000000, 0x02800000, DOMAIN_IO, 0, 1, 0, 0 }, /* static memory bank 2  CS#2 */
+  { H3600_BANK_4_VIRT, 0x40000000, 0x00800000, DOMAIN_IO, 0, 1, 0, 0 }, /* static memory bank 4  CS#4 */
   LAST_DESC
 };
 
@@ -214,13 +493,19 @@
 	sa1100_register_uart_fns(&h3600_port_fns);
 	sa1100_register_uart(0, 3);
 	sa1100_register_uart(1, 1); /* isn't this one driven elsewhere? */
-	init_h3600_egpio();
 
 	/*
-	 * Default GPIO settings.
+	 * Default GPIO settings.  Should be set by machine
 	 */
 	GPCR = 0x0fffffff;
-	GPDR = 0x0401f3fc;
+//	GPDR = 0x0401f3fc;
+	GPDR = GPIO_H3600_COM_RTS  | GPIO_H3600_L3_CLOCK |
+	       GPIO_H3600_L3_MODE  | GPIO_H3600_L3_DATA  |
+	       GPIO_H3600_CLK_SET1 | GPIO_H3600_CLK_SET0 |
+	       GPIO_LDD15 | GPIO_LDD14 | GPIO_LDD13 | GPIO_LDD12 |
+	       GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9  | GPIO_LDD8;
+
+	init_h3600_egpio();
 
 	/*
 	 * Ensure those pins are outputs and driving low.
@@ -230,11 +515,24 @@
 
 	/* Configure suspend conditions */
 	PGSR = 0;
-	PWER = 0x1 | (1 << 31);
-	PCFR = PCFR_OPDE | PCFR_FP | PCFR_FS;
-}
-
-MACHINE_START(H3600, "Compaq iPAQ")
+	PWER = PWER_GPIO0 | PWER_RTC;
+	PCFR = PCFR_OPDE;
+	PSDR = 0;
+}
+
+MACHINE_START(H3600, "Compaq iPAQ H3600")
+	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+	BOOT_PARAMS(0xc0000100)
+	MAPIO(h3600_map_io)
+	INITIRQ(sa1100_init_irq)
+MACHINE_END
+MACHINE_START(H3100, "Compaq iPAQ H3100")
+	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+	BOOT_PARAMS(0xc0000100)
+	MAPIO(h3600_map_io)
+	INITIRQ(sa1100_init_irq)
+MACHINE_END
+MACHINE_START(H3800, "Compaq iPAQ H3800")
 	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
 	BOOT_PARAMS(0xc0000100)
 	MAPIO(h3600_map_io)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/huw_webpanel.c linux/arch/arm/mach-sa1100/huw_webpanel.c
--- linux.orig/arch/arm/mach-sa1100/huw_webpanel.c	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/mach-sa1100/huw_webpanel.c	Tue May 28 22:39:26 2002
@@ -2,8 +2,6 @@
  * linux/arch/arm/mach-sa1100/huw_webpanel.c
  *
  */
-
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -55,8 +53,8 @@
 **/
 static struct map_desc huw_webpanel_io_desc[] __initdata = {
  /* virtual     physical    length      domain     r  w  c  b */
-  { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0, neccessary for mtd */
-  { 0xf0000000, 0xc1fb8000, 0x00048000, DOMAIN_IO, 1, 1, 0, 0 }, /* Parameter */
+  { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 0, neccessary for mtd */
+  { 0xf0000000, 0xc1fb8000, 0x00048000, DOMAIN_IO, 0, 1, 0, 0 }, /* Parameter */
   { 0xf1000000, 0x18000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* Paules CS3, write only */
   LAST_DESC
 };
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/irq.c linux/arch/arm/mach-sa1100/irq.c
--- linux.orig/arch/arm/mach-sa1100/irq.c	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/mach-sa1100/irq.c	Tue May 28 22:39:31 2002
@@ -9,12 +9,11 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
+#include <linux/ioport.h>
 #include <linux/ptrace.h>
 
 #include <asm/hardware.h>
@@ -35,8 +34,13 @@
 static int GPIO_IRQ_rising_edge;
 static int GPIO_IRQ_falling_edge;
 
-void set_GPIO_IRQ_edge( int gpio_mask, int edge )
+void set_GPIO_IRQ_edge(int gpio_mask, int edge)
 {
+	long flags;
+	int irq = 0;
+
+	gpio_mask &= 0x0fffffff;
+	local_irq_save(flags);
 	if (edge & GPIO_FALLING_EDGE)
 		GPIO_IRQ_falling_edge |= gpio_mask;
 	else
@@ -45,6 +49,17 @@
 		GPIO_IRQ_rising_edge |= gpio_mask;
 	else
 		GPIO_IRQ_rising_edge &= ~gpio_mask;
+	GPDR &= ~gpio_mask;
+	GAFR &= ~gpio_mask;
+	while (gpio_mask) {
+		if (irq == 11)
+			irq = IRQ_GPIO11;
+		if (gpio_mask & 1)
+			irq_desc[irq].valid = 1;
+		irq++;
+		gpio_mask >>= 1;
+	}
+	local_irq_restore(flags);
 }
 
 EXPORT_SYMBOL(set_GPIO_IRQ_edge);
@@ -121,7 +136,7 @@
 
 		for (i = 11; i <= 27; ++i) {
 			if (irq & (1<<i)) {
-				do_IRQ (IRQ_GPIO_11_27(i), regs);
+				do_IRQ(IRQ_GPIO11 + i - 11, regs);
 			}
 		}
 	}
@@ -175,11 +190,18 @@
 	GFER = (GFER & ~mask) | (GPIO_IRQ_falling_edge & mask);
 }
 
+static struct resource irq_resource = {
+	name:	"irqs",
+	start:	0x90050000,
+	end:	0x9005ffff,
+};
 
 void __init sa1100_init_irq(void)
 {
 	int irq;
 
+	request_resource(&iomem_resource, &irq_resource);
+
 	/* disable all IRQs */
 	ICMR = 0;
 
@@ -197,8 +219,13 @@
 	 */
 	ICCR = 1;
 
+	/*
+	 * Note: GPIO IRQs are initially invalid until at least one call
+	 * to set_GPIO_IRQ_edge() is performed.
+	 */
+
 	for (irq = 0; irq <= 10; irq++) {
-		irq_desc[irq].valid	= 1;
+		irq_desc[irq].valid	= 0;
 		irq_desc[irq].probe_ok	= 1;
 		irq_desc[irq].mask_ack	= sa1100_mask_and_ack_GPIO0_10_irq;
 		irq_desc[irq].mask	= sa1100_mask_GPIO0_10_irq;
@@ -214,7 +241,7 @@
 	}
 
 	for (irq = 32; irq <= 48; irq++) {
-		irq_desc[irq].valid	= 1;
+		irq_desc[irq].valid	= 0;
 		irq_desc[irq].probe_ok	= 1;
 		irq_desc[irq].mask_ack	= sa1100_mask_and_ack_GPIO11_27_irq;
 		irq_desc[irq].mask	= sa1100_mask_GPIO11_27_irq;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/itsy.c linux/arch/arm/mach-sa1100/itsy.c
--- linux.orig/arch/arm/mach-sa1100/itsy.c	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/mach-sa1100/itsy.c	Tue May 28 22:39:21 2002
@@ -31,8 +31,8 @@
    likely wrong. */
 static struct map_desc itsy_io_desc[] __initdata = {
  /* virtual     physical    length      domain     r  w  c  b */
-  { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */
-  { 0xf0000000, 0x49000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* EGPIO 0 */
+  { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 0 */
+  { 0xf0000000, 0x49000000, 0x01000000, DOMAIN_IO, 0, 1, 0, 0 }, /* EGPIO 0 */
   LAST_DESC
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/jornada720.c linux/arch/arm/mach-sa1100/jornada720.c
--- linux.orig/arch/arm/mach-sa1100/jornada720.c	Thu Oct 11 16:04:57 2001
+++ linux/arch/arm/mach-sa1100/jornada720.c	Tue May 28 22:39:28 2002
@@ -37,20 +37,17 @@
 	SKCR = JORSKCR_INIT;	/* Turn on the PLL, enable Ready and enable nOE assertion from DC */
 	mdelay(100);
 
-	SKCR = JORSKCR_RCLK;	/* turn on the RCLOCK */
-	SMCR = 0x35;	/* initialize the SMC (debug SA-1111 reset */
-	PCCR = 0;	/* initialize the S2MC (debug SA-1111 reset) */
+	SBI_SKCR = JORSKCR_RCLK;/* turn on the RCLOCK */
+	SBI_SMCR = 0x35;	/* initialize the SMC (debug SA-1111 reset */
+	PCCR = 0;		/* initialize the S2MC (debug SA-1111 reset) */
 
 	/* LDD4 is speaker, LDD3 is microphone */
 	PPSR &= ~(PPC_LDD3 | PPC_LDD4);
 	PPDR |= PPC_LDD3 | PPC_LDD4;
 
 	/* initialize extra IRQs */
-	set_GPIO_IRQ_edge(GPIO_GPIO(1), GPIO_RISING_EDGE);
-	sa1111_init_irq(SA1100_GPIO_TO_IRQ(1));	/* chained on GPIO 1 */
-
-	sa1100_register_uart(0, 3);
-	sa1100_register_uart(1, 1);
+	set_GPIO_IRQ_edge(GPIO_GPIO1, GPIO_RISING_EDGE);
+	sa1111_init_irq(IRQ_GPIO1);	/* chained on GPIO 1 */
 
 	return 0;
 }
@@ -68,10 +65,10 @@
 
 static struct map_desc jornada720_io_desc[] __initdata = {
  /* virtual     physical    length      domain     r  w  c  b */
-  { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */
-  { 0xf0000000, 0x48000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* Epson registers */
-  { 0xf1000000, 0x48200000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* Epson frame buffer */
-  { 0xf4000000, 0x40000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* SA-1111 */
+  { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 0 */
+  { 0xf0000000, 0x48000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* Epson registers */
+  { 0xf1000000, 0x48200000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* Epson frame buffer */
+  { 0xf4000000, 0x40000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* SA-1111 */
   LAST_DESC
 };
 
@@ -79,6 +76,9 @@
 {
 	sa1100_map_io();
 	iotable_init(jornada720_io_desc);
+	
+	sa1100_register_uart(0, 3);
+	sa1100_register_uart(1, 1);
 }
 
 MACHINE_START(JORNADA720, "HP Jornada 720")
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/lart.c linux/arch/arm/mach-sa1100/lart.c
--- linux.orig/arch/arm/mach-sa1100/lart.c	Mon Aug 13 00:36:24 2001
+++ linux/arch/arm/mach-sa1100/lart.c	Tue May 28 22:39:26 2002
@@ -18,8 +18,8 @@
 
 static struct map_desc lart_io_desc[] __initdata = {
  /* virtual     physical    length      domain     r  w  c  b */
-  { 0xe8000000, 0x00000000, 0x00400000, DOMAIN_IO, 1, 1, 0, 0 }, /* main flash memory */
-  { 0xec000000, 0x08000000, 0x00400000, DOMAIN_IO, 1, 1, 0, 0 }, /* main flash, alternative location */
+  { 0xe8000000, 0x00000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* main flash memory */
+  { 0xec000000, 0x08000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* main flash, alternative location */
   LAST_DESC
 };
 
@@ -31,6 +31,7 @@
 	sa1100_register_uart(0, 3);
 	sa1100_register_uart(1, 1);
 	sa1100_register_uart(2, 2);
+
 	GAFR |= (GPIO_UART_TXD | GPIO_UART_RXD);
 	GPDR |= GPIO_UART_TXD;
 	GPDR &= ~GPIO_UART_RXD;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/leds-assabet.c linux/arch/arm/mach-sa1100/leds-assabet.c
--- linux.orig/arch/arm/mach-sa1100/leds-assabet.c	Thu Oct 25 20:53:46 2001
+++ linux/arch/arm/mach-sa1100/leds-assabet.c	Tue May 28 22:39:25 2002
@@ -42,6 +42,8 @@
 
 	case led_stop:
 		led_state &= ~LED_STATE_ENABLED;
+		hw_led_state = ASSABET_BCR_LED_RED | ASSABET_BCR_LED_GREEN;
+		ASSABET_BCR_frob(ASSABET_BCR_LED_MASK, hw_led_state);
 		break;
 
 	case led_claim:
@@ -107,8 +109,7 @@
 	}
 
 	if  (led_state & LED_STATE_ENABLED)
-		ASSABET_BCR = BCR_value = (BCR_value & ~ASSABET_BCR_LED_MASK) |
-			hw_led_state;
+		ASSABET_BCR_frob(ASSABET_BCR_LED_MASK, hw_led_state);
 
 	local_irq_restore(flags);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/leds-flexanet.c linux/arch/arm/mach-sa1100/leds-flexanet.c
--- linux.orig/arch/arm/mach-sa1100/leds-flexanet.c	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/mach-sa1100/leds-flexanet.c	Tue May 28 22:39:15 2002
@@ -35,7 +35,7 @@
 	switch (evt) {
 	case led_start:
 		/* start using LEDs and enable its hardware */
-		hw_led_bcr = BCR_LED_GREEN;
+		hw_led_bcr = FHH_BCR_LED_GREEN;
 		hw_led_gpio = GPIO_LED_RED;
 		led_state = LED_STATE_ENABLED;
 		break;
@@ -71,13 +71,13 @@
 	case led_idle_start:
 		/* turn off CPU load LED */
 		if (!(led_state & LED_STATE_CLAIMED))
-			hw_led_bcr &= ~BCR_LED_GREEN;
+			hw_led_bcr &= ~FHH_BCR_LED_GREEN;
 		break;
 
 	case led_idle_end:
 		/* turn on CPU load LED */
 		if (!(led_state & LED_STATE_CLAIMED))
-			hw_led_bcr |= BCR_LED_GREEN;
+			hw_led_bcr |= FHH_BCR_LED_GREEN;
 		break;
 #endif
 
@@ -88,12 +88,12 @@
 	/* direct LED access (must be previously claimed) */
 	case led_green_on:
 		if (led_state & LED_STATE_CLAIMED)
-			hw_led_bcr |= BCR_LED_GREEN;
+			hw_led_bcr |= FHH_BCR_LED_GREEN;
 		break;
 
 	case led_green_off:
 		if (led_state & LED_STATE_CLAIMED)
-			hw_led_bcr &= ~BCR_LED_GREEN;
+			hw_led_bcr &= ~FHH_BCR_LED_GREEN;
 		break;
 
 	case led_amber_on:
@@ -119,7 +119,7 @@
 	if  (led_state & LED_STATE_ENABLED)
 	{
 		/* update LEDs */
-		BCR = BCR_value = (BCR_value & ~BCR_LED_GREEN) | hw_led_bcr;
+		FHH_BCR = flexanet_BCR = (flexanet_BCR & ~FHH_BCR_LED_GREEN) | hw_led_bcr;
 		GPSR = hw_led_gpio;
 		GPCR = hw_led_gpio ^ GPIO_LED_RED;
 	}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/leds-frodo.c linux/arch/arm/mach-sa1100/leds-frodo.c
--- linux.orig/arch/arm/mach-sa1100/leds-frodo.c	Thu Jan  1 00:00:00 1970
+++ linux/arch/arm/mach-sa1100/leds-frodo.c	Tue May 28 22:39:13 2002
@@ -0,0 +1,121 @@
+
+/*
+ * linux/arch/arm/mach-sa1100/leds-frodo.c
+ *
+ * Author: Abraham van der Merwe <abraham@2d3d.co.za>
+ *
+ * This file contains the 2d3D, Inc. SA-1110 Development Board LED
+ * event handler.
+ *
+ * Frodo LEDs
+ *
+ *   - led6 - toggles state every 50 timer interrupts (Heartbeat)
+ *   - led7 - on if system is not idle (CPU load)
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+
+#include "leds.h"
+
+#define led6_on() FRODO_CPLD_GENERAL |= FRODO_LED2
+#define led6_off() FRODO_CPLD_GENERAL &= ~FRODO_LED2
+#define led6_invert() do {						\
+		if ((FRODO_CPLD_GENERAL & FRODO_LED2))	\
+			led6_off ();						\
+		else									\
+			led6_on ();							\
+	} while (0)
+
+#define led7_on() FRODO_CPLD_GENERAL |= FRODO_LED1
+#define led7_off() FRODO_CPLD_GENERAL &= ~FRODO_LED1
+#define led7_invert() do {						\
+		if ((FRODO_CPLD_GENERAL & FRODO_LED1))	\
+			led7_off ();						\
+		else									\
+			led7_on ();							\
+	} while (0)
+
+static int claimed;
+
+void frodo_leds_event (led_event_t evt)
+{
+   unsigned long flags;
+
+   local_irq_save (flags);
+
+   switch (evt)
+	 {
+#ifdef CONFIG_LEDS_CPU
+		/* turn off CPU load LED */
+	  case led_idle_start:
+		if (!claimed) led7_off ();
+		break;
+
+		/* turn on CPU load LED */
+	  case led_idle_end:
+		if (!claimed) led7_on ();
+		break;
+#endif
+
+#ifdef CONFIG_LEDS_TIMER
+		/* toggle heartbeat LED */
+	  case led_timer:
+		if (!claimed) led6_invert ();
+		break;
+#endif
+
+		/* start: turn on LEDs and set claimed to 0 */
+	  case led_start:
+		led6_on ();
+		led7_on ();
+		claimed = 0;
+		break;
+
+		/* stop: turn off LEDs */
+	  case led_stop:
+		led6_off ();
+		led7_off ();
+		break;
+
+		/* override CPU load & timer LEDs */
+	  case led_claim:
+		claimed = 1;
+		break;
+
+		/* restore CPU load & timer LEDs */
+	  case led_release:
+		claimed = 0;
+		break;
+
+		/* direct LED access (must be previously claimed) */
+
+		/* led7 */
+	  case led_green_on:
+		if (claimed) led7_on ();
+		break;
+
+	  case led_green_off:
+		if (claimed) led7_off ();
+		break;
+
+		/* led6 -- at the moment this is actually also green */
+	  case led_red_on:
+		if (claimed) led6_on ();
+		break;
+
+	  case led_red_off:
+		if (claimed) led6_off ();
+		break;
+
+	  default:
+		break;
+	}
+
+   local_irq_restore (flags);
+}
+
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/leds-system3.c linux/arch/arm/mach-sa1100/leds-system3.c
--- linux.orig/arch/arm/mach-sa1100/leds-system3.c	Thu Jan  1 00:00:00 1970
+++ linux/arch/arm/mach-sa1100/leds-system3.c	Tue May 28 22:39:22 2002
@@ -0,0 +1,47 @@
+/*
+ * linux/arch/arm/mach-sa1100/leds-system3.c
+ *
+ * Copyright (C) 2001 Stefan Eletzhofer <stefan.eletzhofer@gmx.de>
+ *
+ * Original (leds-footbridge.c) by Russell King
+ *
+ * $Id: leds-system3.c,v 1.1.6.1 2001/12/04 15:19:26 seletz Exp $
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * $Log: leds-system3.c,v $
+ * Revision 1.1.6.1  2001/12/04 15:19:26  seletz
+ * - merged from linux_2_4_13_ac5_rmk2
+ *
+ * Revision 1.1.4.2  2001/11/19 17:58:53  seletz
+ * - cleanup
+ *
+ * Revision 1.1.4.1  2001/11/16 13:49:54  seletz
+ * - dummy LED support for PT Digital Board
+ *
+ * Revision 1.1.2.1  2001/10/15 16:03:39  seletz
+ * - dummy function
+ *
+ *
+ */
+#include <linux/init.h>
+
+#include <asm/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+
+#include "leds.h"
+
+
+#define LED_STATE_ENABLED	1
+#define LED_STATE_CLAIMED	2
+
+static unsigned int led_state;
+static unsigned int hw_led_state;
+
+void system3_leds_event(led_event_t evt)
+{
+	/* TODO: support LEDs */
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/leds.c linux/arch/arm/mach-sa1100/leds.c
--- linux.orig/arch/arm/mach-sa1100/leds.c	Thu Oct 25 20:53:46 2001
+++ linux/arch/arm/mach-sa1100/leds.c	Tue May 28 22:39:18 2002
@@ -5,7 +5,6 @@
  * 
  * Copyright (C) 2001 Nicolas Pitre
  */
-#include <linux/config.h>
 #include <linux/init.h>
 
 #include <asm/leds.h>
@@ -16,24 +15,30 @@
 static int __init
 sa1100_leds_init(void)
 {
+	if (machine_is_adsbitsy())
+		leds_event = adsbitsy_leds_event;
 	if (machine_is_assabet())
 		leds_event = assabet_leds_event;
+ 	if (machine_is_consus())
+ 	        leds_event = consus_leds_event;
 	if (machine_is_brutus())
 		leds_event = brutus_leds_event;
 	if (machine_is_cerf())
 		leds_event = cerf_leds_event;
 	if (machine_is_flexanet())
 		leds_event = flexanet_leds_event;
+	if (machine_is_frodo())
+		leds_event = frodo_leds_event;
 	if (machine_is_graphicsclient())
 		leds_event = graphicsclient_leds_event;
+	if (machine_is_graphicsmaster())
+		leds_event = graphicsmaster_leds_event;
 	if (machine_is_lart())
 		leds_event = lart_leds_event;
 	if (machine_is_pfs168())
 		leds_event = pfs168_leds_event;
-	if (machine_is_graphicsmaster())
-		leds_event = graphicsmaster_leds_event;
-	if (machine_is_adsbitsy())
-		leds_event = adsbitsy_leds_event;
+	if (machine_is_pt_system3())
+		leds_event = system3_leds_event;
 
 	leds_event(led_start);
 	return 0;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/leds.h linux/arch/arm/mach-sa1100/leds.h
--- linux.orig/arch/arm/mach-sa1100/leds.h	Thu Oct 25 20:53:46 2001
+++ linux/arch/arm/mach-sa1100/leds.h	Tue May 28 22:39:19 2002
@@ -1,4 +1,5 @@
 extern void assabet_leds_event(led_event_t evt);
+extern void consus_leds_event(led_event_t evt);
 extern void brutus_leds_event(led_event_t evt);
 extern void cerf_leds_event(led_event_t evt);
 extern void flexanet_leds_event(led_event_t evt);
@@ -7,3 +8,5 @@
 extern void pfs168_leds_event(led_event_t evt);
 extern void graphicsmaster_leds_event(led_event_t evt);
 extern void adsbitsy_leds_event(led_event_t evt);
+extern void system3_leds_event(led_event_t evt);
+extern void frodo_leds_event(led_event_t evt);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/nanoengine.c linux/arch/arm/mach-sa1100/nanoengine.c
--- linux.orig/arch/arm/mach-sa1100/nanoengine.c	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/mach-sa1100/nanoengine.c	Tue May 28 22:39:12 2002
@@ -34,9 +34,9 @@
 
 static struct map_desc nanoengine_io_desc[] __initdata = {
  /* virtual     physical    length      domain     r  w  c  b */
-  { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */
-  { 0xf0000000, 0x10000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* System Registers */
-  { 0xf1000000, 0x18A00000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* Internal PCI Config Space */
+  { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 0 */
+  { 0xf0000000, 0x10000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* System Registers */
+  { 0xf1000000, 0x18A00000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* Internal PCI Config Space */
   LAST_DESC
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/neponset.c linux/arch/arm/mach-sa1100/neponset.c
--- linux.orig/arch/arm/mach-sa1100/neponset.c	Thu Oct 25 20:53:46 2001
+++ linux/arch/arm/mach-sa1100/neponset.c	Tue May 28 22:39:27 2002
@@ -7,6 +7,8 @@
 #include <linux/sched.h>
 #include <linux/interrupt.h>
 #include <linux/ptrace.h>
+#include <linux/tty.h>
+#include <linux/ioport.h>
 #include <linux/serial_core.h>
 
 #include <asm/hardware.h>
@@ -16,6 +18,7 @@
 #include <asm/arch/irq.h>
 #include <asm/mach/serial_sa1100.h>
 #include <asm/arch/assabet.h>
+#include <asm/hardware/sa1111.h>
 
 #include "sa1111.h"
 
@@ -40,10 +43,10 @@
 		if (!irr) break;
 
 		if( irr & IRR_ETHERNET )
-			do_IRQ(NEPONSET_ETHERNET_IRQ, regs);
+			do_IRQ(IRQ_NEPONSET_SMC9196, regs);
 
 		if( irr & IRR_USAR )
-			do_IRQ(NEPONSET_USAR_IRQ, regs);
+			do_IRQ(IRQ_NEPONSET_USAR, regs);
 
 		if( irr & IRR_SA1111 )
 			sa1111_IRQ_demux(irq, dev_id, regs);
@@ -58,19 +61,16 @@
 
 static void __init neponset_init_irq(void)
 {
-	int irq;
-
 	sa1111_init_irq(-1);	/* SA1111 IRQ not routed to a GPIO */
 
 	/* setup extra Neponset IRQs */
-	irq = NEPONSET_ETHERNET_IRQ;
-	irq_desc[irq].valid	= 1;
-	irq_desc[irq].probe_ok	= 1;
-	irq = NEPONSET_USAR_IRQ;
-	irq_desc[irq].valid	= 1;
-	irq_desc[irq].probe_ok	= 1;
-	set_GPIO_IRQ_edge(ASSABET_GPIO_NEP_IRQ, GPIO_RISING_EDGE);
-	setup_arm_irq(ASSABET_IRQ_GPIO_NEP_IRQ, &neponset_irq);
+	irq_desc[IRQ_NEPONSET_SMC9196].valid	= 1;
+	irq_desc[IRQ_NEPONSET_SMC9196].probe_ok	= 1;
+	irq_desc[IRQ_NEPONSET_USAR].valid	= 1;
+	irq_desc[IRQ_NEPONSET_USAR].probe_ok	= 1;
+
+	set_GPIO_IRQ_edge(GPIO_GPIO25, GPIO_RISING_EDGE);
+	setup_arm_irq(IRQ_GPIO25, &neponset_irq);
 }
 
 static int __init neponset_init(void)
@@ -102,6 +102,11 @@
 	}
 
 	/*
+	 * Disable GPIO 0/1 drivers so the buttons work on the module.
+	 */
+	NCR_0 |= NCR_GP01_OFF;
+
+	/*
 	 * Neponset has SA1111 connected to CS4.  We know that after
 	 * reset the chip will be configured for variable latency IO.
 	 */
@@ -110,7 +115,7 @@
 	/*
 	 * Probe for a SA1111.
 	 */
-	ret = sa1111_probe();
+	ret = sa1111_probe(NEPONSET_SA1111_BASE);
 	if (ret < 0)
 		return ret;
 
@@ -150,8 +155,8 @@
 
 static struct map_desc neponset_io_desc[] __initdata = {
  /* virtual     physical    length      domain     r  w  c  b */
-  { 0xf3000000, 0x10000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* System Registers */
-  { 0xf4000000, 0x40000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* SA-1111 */
+  { 0xf3000000, 0x10000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* System Registers */
+  { 0xf4000000, 0x40000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* SA-1111 */
   LAST_DESC
 };
 
@@ -184,7 +189,7 @@
 	MDM_CTL_0 = mdm_ctl0;
 }
 
-static int neponset_get_mctrl(struct uart_port *port)
+static u_int neponset_get_mctrl(struct uart_port *port)
 {
 	u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
 	u_int mdm_ctl1 = MDM_CTL_1;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/omnimeter.c linux/arch/arm/mach-sa1100/omnimeter.c
--- linux.orig/arch/arm/mach-sa1100/omnimeter.c	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/mach-sa1100/omnimeter.c	Tue May 28 22:39:12 2002
@@ -30,7 +30,7 @@
 
 static struct map_desc omnimeter_io_desc[] __initdata = {
  /* virtual     physical    length      domain     r  w  c  b */
-  { 0xd2000000, 0x10000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* TS */
+  { 0xd2000000, 0x10000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* TS */
   LAST_DESC
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/pangolin.c linux/arch/arm/mach-sa1100/pangolin.c
--- linux.orig/arch/arm/mach-sa1100/pangolin.c	Thu Oct 11 16:04:57 2001
+++ linux/arch/arm/mach-sa1100/pangolin.c	Tue May 28 22:39:24 2002
@@ -1,7 +1,7 @@
 /*
  * linux/arch/arm/mach-sa1100/pangolin.c
  */
-
+#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/tty.h>
@@ -30,8 +30,8 @@
 
 static struct map_desc pangolin_io_desc[] __initdata = {
  /* virtual     physical    length      domain     r  w  c  b */
-  { 0xe8000000, 0x00000000, 0x04000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */
-  { 0xf2800000, 0x4b800000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* MQ200 */
+  { 0xe8000000, 0x00000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 0 */
+  { 0xf2800000, 0x4b800000, 0x00800000, DOMAIN_IO, 0, 1, 0, 0 }, /* MQ200 */
   LAST_DESC
 };
 
@@ -43,6 +43,12 @@
 	sa1100_register_uart(0, 1);
 	sa1100_register_uart(1, 3);
 	Ser1SDCR0 |= SDCR0_UART;
+
+	/* set some GPDR bits while it's safe */
+	GPDR |= GPIO_PCMCIA_RESET;
+#ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
+	GPDR |= GPIO_PCMCIA_BUS_ON;
+#endif
 }
 
 MACHINE_START(PANGOLIN, "Dialogue-Pangolin")
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/pfs168.c linux/arch/arm/mach-sa1100/pfs168.c
--- linux.orig/arch/arm/mach-sa1100/pfs168.c	Thu Oct 11 16:04:57 2001
+++ linux/arch/arm/mach-sa1100/pfs168.c	Tue May 28 22:39:12 2002
@@ -1,7 +1,7 @@
 /*
  * linux/arch/arm/mach-sa1100/pfs168.c
  */
-
+#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/tty.h>
@@ -34,7 +34,7 @@
 	/*
 	 * Probe for SA1111.
 	 */
-	ret = sa1111_probe();
+	ret = sa1111_probe(PFS168_SA1111_BASE);
 	if (ret < 0)
 		return ret;
 
@@ -65,8 +65,7 @@
 	 */
 	sa1110_mb_enable();
 
-	set_GPIO_IRQ_edge(GPIO_GPIO(25), GPIO_RISING_EDGE);
-	sa1111_init_irq(SA1100_GPIO_TO_IRQ(25));	/* SA1111 IRQ on GPIO 25 */
+	sa1111_init_irq(IRQ_GPIO25);	/* SA1111 IRQ on GPIO 25 */
 
 	return 0;
 }
@@ -84,6 +83,8 @@
 	 */
 	set_GPIO_IRQ_edge(GPIO_GPIO(19), GPIO_RISING_EDGE);
 	set_GPIO_IRQ_edge(GPIO_GPIO(20), GPIO_RISING_EDGE);
+	set_GPIO_IRQ_edge(GPIO_GPIO(25), GPIO_RISING_EDGE);
+	set_GPIO_IRQ_edge(GPIO_UCB1300_IRQ, GPIO_RISING_EDGE);
 }
 
 
@@ -101,20 +102,20 @@
 
 static struct map_desc pfs168_io_desc[] __initdata = {
  /* virtual     physical    length      domain     r  w  c  b */
-  { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */
-  { 0xf0000000, 0x10000000, 0x00001000, DOMAIN_IO, 1, 1, 0, 0 }, /* 16C752 DUART port A (COM5) */
-  { 0xf0001000, 0x10800000, 0x00001000, DOMAIN_IO, 1, 1, 0, 0 }, /* 16C752 DUART port B (COM6) */
-  { 0xf0002000, 0x11000000, 0x00001000, DOMAIN_IO, 1, 1, 0, 0 }, /* COM1 RTS control (SYSC1RTS) */
-  { 0xf0003000, 0x11400000, 0x00001000, DOMAIN_IO, 1, 1, 0, 0 }, /* Status LED control (SYSLED) */
-  { 0xf0004000, 0x11800000, 0x00001000, DOMAIN_IO, 1, 1, 0, 0 }, /* DTMF code read (SYSDTMF) */
-  { 0xf0005000, 0x11c00000, 0x00001000, DOMAIN_IO, 1, 1, 0, 0 }, /* LCD configure, enable (SYSLCDDE) */
-  { 0xf0006000, 0x12000000, 0x00001000, DOMAIN_IO, 1, 1, 0, 0 }, /* COM1 DSR and motion sense (SYSC1DSR) */
-  { 0xf0007000, 0x12800000, 0x00001000, DOMAIN_IO, 1, 1, 0, 0 }, /* COM3 xmit enable (SYSC3TEN) */
-  { 0xf0008000, 0x13000000, 0x00001000, DOMAIN_IO, 1, 1, 0, 0 }, /* Control register A (SYSCTLA) */
-  { 0xf0009000, 0x13800000, 0x00001000, DOMAIN_IO, 1, 1, 0, 0 }, /* Control register B (SYSCTLB) */
-  { 0xf000a000, 0x18000000, 0x00001000, DOMAIN_IO, 1, 1, 0, 0 }, /* SMC91C96 */
-  { 0xf2800000, 0x4b800000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* MQ200 */
-  { 0xf4000000, 0x40000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* SA-1111 */
+  { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 0 */
+  { 0xf0000000, 0x10000000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, /* 16C752 DUART port A (COM5) */
+  { 0xf0001000, 0x10800000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, /* 16C752 DUART port B (COM6) */
+  { 0xf0002000, 0x11000000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, /* COM1 RTS control (SYSC1RTS) */
+  { 0xf0003000, 0x11400000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, /* Status LED control (SYSLED) */
+  { 0xf0004000, 0x11800000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, /* DTMF code read (SYSDTMF) */
+  { 0xf0005000, 0x11c00000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, /* LCD configure, enable (SYSLCDDE) */
+  { 0xf0006000, 0x12000000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, /* COM1 DSR and motion sense (SYSC1DSR) */
+  { 0xf0007000, 0x12800000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, /* COM3 xmit enable (SYSC3TEN) */
+  { 0xf0008000, 0x13000000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, /* Control register A (SYSCTLA) */
+  { 0xf0009000, 0x13800000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, /* Control register B (SYSCTLB) */
+  { 0xf000a000, 0x18000000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, /* SMC91C96 */
+  { 0xf2800000, 0x4b800000, 0x00800000, DOMAIN_IO, 0, 1, 0, 0 }, /* MQ200 */
+  { 0xf4000000, 0x40000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* SA-1111 */
   LAST_DESC
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/pleb.c linux/arch/arm/mach-sa1100/pleb.c
--- linux.orig/arch/arm/mach-sa1100/pleb.c	Mon Aug 13 00:36:24 2001
+++ linux/arch/arm/mach-sa1100/pleb.c	Tue May 28 22:39:21 2002
@@ -35,8 +35,8 @@
 
 static struct map_desc pleb_io_desc[] __initdata = {
  /* virtual     physical    length      domain     r  w  c  b */
-  { 0xe8000000, 0x00000000, 0x00400000, DOMAIN_IO, 1, 1, 0, 0 }, /* main flash memory */
-  { 0xe8400000, 0x08000000, 0x00400000, DOMAIN_IO, 1, 1, 0, 0 }, /* main flash, alternative location */
+  { 0xe8000000, 0x00000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* main flash memory */
+  { 0xe8400000, 0x08000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* main flash, alternative location */
   LAST_DESC
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/pm.c linux/arch/arm/mach-sa1100/pm.c
--- linux.orig/arch/arm/mach-sa1100/pm.c	Thu Oct 25 20:53:46 2001
+++ linux/arch/arm/mach-sa1100/pm.c	Tue May 28 22:39:20 2002
@@ -19,30 +19,27 @@
  * 			Cleaned up, pushed platform dependent stuff
  * 			in the platform specific files.
  */
-
-/*
- * Debug macros
- */
-#define DEBUG 1
-#ifdef DEBUG
-#  define DPRINTK(fmt, args...)	printk("%s: " fmt, __FUNCTION__ , ## args)
-#else
-#  define DPRINTK(fmt, args...)
-#endif
-
-
+#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/pm.h>
 #include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
 #include <linux/sysctl.h>
-#include <linux/acpi.h>
+#include <linux/errno.h>
 
 #include <asm/hardware.h>
 #include <asm/memory.h>
 #include <asm/system.h>
+#include <asm/leds.h>
 
 #include "sleep.h"
 
+/*
+ * Debug macros
+ */
+#undef DEBUG
+
 extern void sa1100_cpu_suspend(void);
 extern void sa1100_cpu_resume(void);
 
@@ -54,22 +51,17 @@
 
 int pm_do_suspend(void)
 {
-	int retval;
-
 	/* set up pointer to sleep parameters */
-	sleep_save = kmalloc (SLEEP_SAVE_SIZE*sizeof(long), GFP_ATOMIC);
+	sleep_save = kmalloc(SLEEP_SAVE_SIZE*sizeof(long), GFP_ATOMIC);
 	if (!sleep_save)
 		return -ENOMEM;
-	sleep_save_p = virt_to_phys(sleep_save);
 
-	retval = pm_send_all(PM_SUSPEND, (void *)2);
-	if (retval) {
-		kfree(sleep_save);
-		return retval;
-	}
+	sleep_save_p = virt_to_phys(sleep_save);
 
 	cli();
 
+	leds_event(led_stop);
+
 	/* preserve current time */
 	RCNR = xtime.tv_sec;
 
@@ -112,7 +104,9 @@
 	/* ensure not to come back here if it wasn't intended */
 	PSPR = 0;
 
-	DPRINTK("*** made it back from resume\n");
+#ifdef DEBUG
+	printk(KERN_DEBUG "*** made it back from resume\n");
+#endif
 
 	/* restore registers */
 	RESTORE(GPDR);
@@ -146,21 +140,55 @@
 	/* restore current time */
 	xtime.tv_sec = RCNR;
 
+	leds_event(led_start);
+
 	sti();
 
 	kfree (sleep_save);
 
-	retval = pm_send_all(PM_RESUME, (void *)0);
-	if (retval)
-		return retval;
+	/*
+	 * Restore the CPU frequency settings.
+	 */
+#ifdef CONFIG_CPU_FREQ
+	cpufreq_restore();
+#endif
 
 	return 0;
 }
 
+#ifdef CONFIG_SYSCTL
+/*
+ * ARGH!  ACPI people defined CTL_ACPI in linux/acpi.h rather than
+ * linux/sysctl.h.
+ *
+ * This means our interface here won't survive long - it needs a new
+ * interface.  Quick hack to get this working - use sysctl id 9999.
+ */
+#warning ACPI broke the kernel, this interface needs to be fixed up.
+#define CTL_ACPI 9999
+#define ACPI_S1_SLP_TYP 19
+
+/*
+ * Send us to sleep.
+ */
+static int sysctl_pm_do_suspend(void)
+{
+	int retval;
+
+	retval = pm_send_all(PM_SUSPEND, (void *)3);
+
+	if (retval == 0) {
+		retval = pm_do_suspend();
+
+		pm_send_all(PM_RESUME, (void *)0);
+	}
+
+	return retval;
+}
 
 static struct ctl_table pm_table[] =
 {
-	{ACPI_S1_SLP_TYP, "suspend", NULL, 0, 0600, NULL, (proc_handler *)&pm_do_suspend},
+	{ACPI_S1_SLP_TYP, "suspend", NULL, 0, 0600, NULL, (proc_handler *)&sysctl_pm_do_suspend},
 	{0}
 };
 
@@ -181,3 +209,4 @@
 
 __initcall(pm_init);
 
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/sa1111-pcibuf.c linux/arch/arm/mach-sa1100/sa1111-pcibuf.c
--- linux.orig/arch/arm/mach-sa1100/sa1111-pcibuf.c	Thu Oct 11 16:04:57 2001
+++ linux/arch/arm/mach-sa1100/sa1111-pcibuf.c	Tue May 28 22:39:12 2002
@@ -13,7 +13,6 @@
  *
  *  06/13/2001 - created.
  */
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/sa1111.c linux/arch/arm/mach-sa1100/sa1111.c
--- linux.orig/arch/arm/mach-sa1100/sa1111.c	Thu Oct 11 16:04:57 2001
+++ linux/arch/arm/mach-sa1100/sa1111.c	Tue May 28 22:39:24 2002
@@ -15,6 +15,7 @@
  * All initialization functions provided here are intended to be called
  * from machine specific code with proper arguments when required.
  */
+#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
@@ -22,57 +23,80 @@
 #include <linux/interrupt.h>
 #include <linux/ptrace.h>
 #include <linux/errno.h>
+#include <linux/ioport.h>
 
 #include <asm/hardware.h>
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
 #include <asm/arch/irq.h>
 
+#include <asm/hardware/sa1111.h>
+
 #include "sa1111.h"
 
+struct resource sa1111_resource = {
+	name:	"SA1111",
+};
+
+EXPORT_SYMBOL(sa1111_resource);
+
 /*
- * SA1111  Interrupt support
+ * SA1111 interrupt support
  */
-
-void sa1111_IRQ_demux( int irq, void *dev_id, struct pt_regs *regs )
+void sa1111_IRQ_demux(int irq, void *dev_id, struct pt_regs *regs)
 {
-	int i;
 	unsigned long stat0, stat1;
 
-	for(;;) {
-		stat0 = INTSTATCLR0, stat1 = INTSTATCLR1;
-		if( !stat0 && !stat1 ) break;
-		if( stat0 )
-			for( i = 0; i < 32; i++ )
-				if( stat0 & (1<<i) )
-					do_IRQ( SA1111_IRQ(i), regs );
-
-		if( stat1 )
-			for( i = 32; i < 55; i++ )
-				if( stat1 & (1<<(i-32)) )
-					do_IRQ( SA1111_IRQ(i), regs );
+	while (1) {
+		int i;
+
+		stat0 = INTSTATCLR0;
+		stat1 = INTSTATCLR1;
+
+		if (stat0 == 0 && stat1 == 0)
+			break;
+
+		for (i = IRQ_SA1111_START; stat0; i++, stat0 >>= 1)
+			if (stat0 & 1)
+				do_IRQ(i, regs);
+
+		for (i = IRQ_SA1111_START + 32; stat1; i++, stat1 >>= 1)
+			if (stat1 & 1)
+				do_IRQ(i, regs);
 	}
 }
 
-static struct irqaction sa1111_irq = {
-	name:		"SA1111",
-	handler:	sa1111_IRQ_demux,
-	flags:		SA_INTERRUPT
-};
+#define SA1111_IRQMASK_LO(x)	(1 << (x - IRQ_SA1111_START))
+#define SA1111_IRQMASK_HI(x)	(1 << (x - IRQ_SA1111_START - 32))
 
+/*
+ * A note about masking IRQs:
+ *
+ * The GPIO IRQ edge detection only functions while the IRQ itself is
+ * enabled; edges are not detected while the IRQ is disabled.
+ *
+ * This is especially important for the PCMCIA signals, where we must
+ * pick up every transition.  We therefore do not disable the IRQs
+ * while processing them.
+ *
+ * However, since we are changed to a GPIO on the host processor,
+ * all SA1111 IRQs will be disabled while we're processing any SA1111
+ * IRQ.
+ *
+ * Note also that changing INTPOL while an IRQ is enabled will itself
+ * trigger an IRQ.
+ */
 static void sa1111_mask_and_ack_lowirq(unsigned int irq)
 {
-	unsigned int mask = 1 << (irq - SA1111_IRQ(0));
+	unsigned int mask = SA1111_IRQMASK_LO(irq);
 
-	// broken hardware: interrupt events are lost if they occur
-	// while the interrupts are disabled.
 	//INTEN0 &= ~mask;
 	INTSTATCLR0 = mask;
 }
 
 static void sa1111_mask_and_ack_highirq(unsigned int irq)
 {
-	unsigned int mask = 1 << (irq - SA1111_IRQ(32));
+	unsigned int mask = SA1111_IRQMASK_HI(irq);
 
 	//INTEN1 &= ~mask;
 	INTSTATCLR1 = mask;
@@ -80,27 +104,29 @@
 
 static void sa1111_mask_lowirq(unsigned int irq)
 {
-	//INTEN0 &= ~(1 << (irq - SA1111_IRQ(0)));
+	INTEN0 &= ~SA1111_IRQMASK_LO(irq);
 }
 
 static void sa1111_mask_highirq(unsigned int irq)
 {
-	//INTEN1 &= ~(1 << (irq - SA1111_IRQ(32)));
+	INTEN1 &= ~SA1111_IRQMASK_HI(irq);
 }
 
 static void sa1111_unmask_lowirq(unsigned int irq)
 {
-	INTEN0 |= 1 << (irq - SA1111_IRQ(0));
+	INTEN0 |= SA1111_IRQMASK_LO(irq);
 }
 
 static void sa1111_unmask_highirq(unsigned int irq)
 {
-	INTEN1 |= 1 << ((irq - SA1111_IRQ(32)));
+	INTEN1 |= SA1111_IRQMASK_HI(irq);
 }
 
 void __init sa1111_init_irq(int irq_nr)
 {
-	int irq;
+	int irq, ret;
+
+	request_mem_region(_INTTEST0, 512, "irqs");
 
 	/* disable all IRQs */
 	INTEN0 = 0;
@@ -111,21 +137,21 @@
 	 * specifies that S0ReadyInt and S1ReadyInt should be '1'.
 	 */
 	INTPOL0 = 0;
-	INTPOL1 = 1 << (S0_READY_NINT - SA1111_IRQ(32)) |
-		  1 << (S1_READY_NINT - SA1111_IRQ(32));
+	INTPOL1 = SA1111_IRQMASK_HI(S0_READY_NINT) |
+		  SA1111_IRQMASK_HI(S1_READY_NINT);
 
 	/* clear all IRQs */
 	INTSTATCLR0 = -1;
 	INTSTATCLR1 = -1;
 
-	for (irq = SA1111_IRQ(0); irq <= SA1111_IRQ(26); irq++) {
+	for (irq = IRQ_GPAIN0; irq <= SSPROR; irq++) {
 		irq_desc[irq].valid	= 1;
 		irq_desc[irq].probe_ok	= 0;
 		irq_desc[irq].mask_ack	= sa1111_mask_and_ack_lowirq;
 		irq_desc[irq].mask	= sa1111_mask_lowirq;
 		irq_desc[irq].unmask	= sa1111_unmask_lowirq;
 	}
-	for (irq = SA1111_IRQ(32); irq <= SA1111_IRQ(54); irq++) {
+	for (irq = AUDXMTDMADONEA; irq <= S1_BVD1_STSCHG; irq++) {
 		irq_desc[irq].valid	= 1;
 		irq_desc[irq].probe_ok	= 0;
 		irq_desc[irq].mask_ack	= sa1111_mask_and_ack_highirq;
@@ -134,28 +160,60 @@
 	}
 
 	/* Register SA1111 interrupt */
-	if (irq_nr >= 0)
-		setup_arm_irq(irq_nr, &sa1111_irq);
+	if (irq_nr < 0)
+		return;
+
+	ret = request_irq(irq_nr, sa1111_IRQ_demux, SA_INTERRUPT,
+			  "SA1111", NULL);
+	if (ret < 0)
+		printk(KERN_ERR "SA1111: unable to claim IRQ%d: %d\n",
+		       irq_nr, ret);
 }
 
-/*
- * Probe for a SA1111 chip.
+/**
+ *	sa1111_probe - probe for a single SA1111 chip.
+ *	@phys_addr: physical address of device.
+ *
+ *	Probe for a SA1111 chip.  This must be called
+ *	before any other SA1111-specific code.
+ *
+ *	Returns:
+ *	%-ENODEV	device not found.
+ *	%-EBUSY		physical address already marked in-use.
+ *	%0		successful.
  */
-
-int __init sa1111_probe(void)
+int __init sa1111_probe(unsigned long phys_addr)
 {
-	unsigned long id = SBI_SKID;
+	unsigned long id;
 	int ret = -ENODEV;
 
-	if ((id & SKID_ID_MASK) == SKID_SA1111_ID) {
-		printk(KERN_INFO "SA-1111 Microprocessor Companion Chip: "
-			"silicon revision %lx, metal revision %lx\n",
-			(id & SKID_SIREV_MASK)>>4, (id & SKID_MTREV_MASK));
-		ret = 0;
-	} else {
-		printk(KERN_DEBUG "SA-1111 not detected: ID = %08lx\n", id);
+	sa1111_resource.start = phys_addr;
+	sa1111_resource.end = phys_addr + 0x2000;
+
+	if (request_resource(&iomem_resource, &sa1111_resource)) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	/*
+	 * Probe for the chip.  Only touch the SBI registers.
+	 */
+	id = SBI_SKID;
+	if ((id & SKID_ID_MASK) != SKID_SA1111_ID) {
+		printk(KERN_DEBUG "SA1111 not detected: ID = %08lx\n", id);
+		ret = -ENODEV;
+		goto release;
 	}
 
+	printk(KERN_INFO "SA1111 Microprocessor Companion Chip: "
+		"silicon revision %lx, metal revision %lx\n",
+		(id & SKID_SIREV_MASK)>>4, (id & SKID_MTREV_MASK));
+
+	return 0;
+
+ release:
+	release_resource(&sa1111_resource);
+ out:
 	return ret;
 }
 
@@ -175,6 +233,10 @@
  */
 void sa1111_wake(void)
 {
+	unsigned long flags;
+
+	local_irq_save(flags);
+
 	/*
 	 * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
 	 * (SA-1110 Developer's Manual, section 9.1.2.1)
@@ -210,6 +272,8 @@
 	 * Ensure all clocks are initially off.
 	 */
 	SKPCR = 0;
+
+	local_irq_restore(flags);
 }
 
 void sa1111_doze(void)
@@ -242,12 +306,17 @@
  */
 void __init sa1110_mb_disable(void)
 {
+	unsigned long flags;
+
+	local_irq_save(flags);
+	
 	PGSR &= ~GPIO_MBGNT;
 	GPCR = GPIO_MBGNT;
 	GPDR = (GPDR & ~GPIO_MBREQ) | GPIO_MBGNT;
 
 	GAFR &= ~(GPIO_MBGNT | GPIO_MBREQ);
 
+	local_irq_restore(flags);
 }
 
 /*
@@ -256,10 +325,19 @@
  */
 void __init sa1110_mb_enable(void)
 {
+	unsigned long flags;
+
+	local_irq_save(flags);
+
 	PGSR &= ~GPIO_MBGNT;
 	GPCR = GPIO_MBGNT;
 	GPDR = (GPDR & ~GPIO_MBREQ) | GPIO_MBGNT;
 
 	GAFR |= (GPIO_MBGNT | GPIO_MBREQ);
 	TUCR |= TUCR_MR;
+
+	local_irq_restore(flags);
 }
+
+EXPORT_SYMBOL(sa1111_wake);
+EXPORT_SYMBOL(sa1111_doze);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/sa1111.h linux/arch/arm/mach-sa1100/sa1111.h
--- linux.orig/arch/arm/mach-sa1100/sa1111.h	Thu Oct 11 16:04:57 2001
+++ linux/arch/arm/mach-sa1100/sa1111.h	Tue May 28 22:39:28 2002
@@ -11,7 +11,7 @@
 /*
  * Probe for a SA1111 chip.
  */
-extern int sa1111_probe(void);
+extern int sa1111_probe(unsigned long phys);
 
 /*
  * Wake up a SA1111 chip.
@@ -30,5 +30,5 @@
 
 
 extern void sa1111_init_irq(int irq_nr);
-extern void sa1111_IRQ_demux( int irq, void *dev_id, struct pt_regs *regs );
+extern void sa1111_IRQ_demux(int irq, void *dev_id, struct pt_regs *regs);
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/shannon.c linux/arch/arm/mach-sa1100/shannon.c
--- linux.orig/arch/arm/mach-sa1100/shannon.c	Thu Jan  1 00:00:00 1970
+++ linux/arch/arm/mach-sa1100/shannon.c	Tue May 28 22:39:22 2002
@@ -0,0 +1,47 @@
+/*
+ * linux/arch/arm/mach-sa1100/shannon.c
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/tty.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/serial_sa1100.h>
+
+#include "generic.h"
+
+
+static struct map_desc shannon_io_desc[] __initdata = {
+ /* virtual     physical    length      domain     r  w  c  b */
+  { 0xe8000000, 0x00000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* main flash memory */
+  LAST_DESC
+};
+
+static void __init shannon_map_io(void)
+{
+	sa1100_map_io();
+	iotable_init(shannon_io_desc);
+
+	sa1100_register_uart(0, 3);
+	sa1100_register_uart(1, 1);
+	Ser1SDCR0 |= SDCR0_SUS;
+	GAFR |= (GPIO_UART_TXD | GPIO_UART_RXD);
+	GPDR |= GPIO_UART_TXD;
+	GPDR &= ~GPIO_UART_RXD;
+	PPAR |= PPAR_UPR;
+
+	set_GPIO_IRQ_edge(SHANNON_GPIO_IRQ_CODEC);
+}
+
+MACHINE_START(SHANNON, "Shannon (AKA: Tuxscreen)")
+	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+	BOOT_PARAMS(0xc0000100)
+	MAPIO(shannon_map_io)
+	INITIRQ(sa1100_init_irq)
+MACHINE_END
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/sherman.c linux/arch/arm/mach-sa1100/sherman.c
--- linux.orig/arch/arm/mach-sa1100/sherman.c	Mon Aug 13 00:36:24 2001
+++ linux/arch/arm/mach-sa1100/sherman.c	Tue May 28 22:39:13 2002
@@ -31,7 +31,7 @@
 
 static struct map_desc sherman_io_desc[] __initdata = {
  /* virtual     physical    length      domain     r  w  c  b */
-  { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash*/
+  { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash*/
   LAST_DESC
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/simpad.c linux/arch/arm/mach-sa1100/simpad.c
--- linux.orig/arch/arm/mach-sa1100/simpad.c	Thu Oct 25 20:53:46 2001
+++ linux/arch/arm/mach-sa1100/simpad.c	Tue May 28 22:39:16 2002
@@ -23,18 +23,6 @@
 
 long cs3_shadow;
 
-static int __init simpad_init(void)
-{
-	PSPR = 0xc0008000;
-	GPDR &= ~GPIO_GPIO0;
-	cs3_shadow = (EN1 | EN0 | LED2_ON | DISPLAY_ON | RS232_ON | 
-		      ENABLE_5V | RESET_SIMCARD);
-	*(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow;
-	return 0;
-}
-
-__initcall(simpad_init);
-
 long get_cs3_shadow()
 {
 	return cs3_shadow;
@@ -70,8 +58,8 @@
 
 static struct map_desc simpad_io_desc[] __initdata = {
   /* virtual	physical    length	domain	   r  w  c  b */
-  { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, 
-  { 0xf2800000, 0x4b800000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* MQ200 */  
+  { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, 
+  { 0xf2800000, 0x4b800000, 0x00800000, DOMAIN_IO, 0, 1, 0, 0 }, /* MQ200 */  
   { 0xf1000000, 0x18000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* Paules CS3, write only */
   LAST_DESC
 };
@@ -96,11 +84,17 @@
 	sa1100_map_io();
 	iotable_init(simpad_io_desc);
 
-#ifndef CONFIG_SERIAL_SA1100_OLD
+	PSPR = 0xc0008000;
+	GPDR &= ~GPIO_GPIO0;
+	cs3_shadow = (EN1 | EN0 | LED2_ON | DISPLAY_ON | RS232_ON | 
+		      ENABLE_5V | RESET_SIMCARD);
+	*(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow;
+
 	//It is only possible to register 3 UART in serial_sa1100.c
 	sa1100_register_uart(0, 3);
 	sa1100_register_uart(1, 1);
-#endif
+
+	set_GPIO_IRQ_edge(GPIO_UCB1300_IRQ, GPIO_RISING_EDGE);
 }
 
 #ifdef CONFIG_PROC_FS
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/system3.c linux/arch/arm/mach-sa1100/system3.c
--- linux.orig/arch/arm/mach-sa1100/system3.c	Thu Jan  1 00:00:00 1970
+++ linux/arch/arm/mach-sa1100/system3.c	Tue May 28 22:39:12 2002
@@ -0,0 +1,379 @@
+/*
+ * linux/arch/arm/mach-sa1100/system3.c
+ *
+ * Copyright (C) 2001 Stefan Eletzhofer <stefan.eletzhofer@eletztrick.de>
+ *
+ * $Id: system3.c,v 1.1.6.1 2001/12/04 17:28:06 seletz Exp $
+ *
+ * This file contains all PT Sytsem 3 tweaks. Based on original work from
+ * Nicolas Pitre's assabet fixes
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * $Log: system3.c,v $
+ * Revision 1.1.6.1  2001/12/04 17:28:06  seletz
+ * - merged from previous branch
+ *
+ * Revision 1.1.4.3  2001/12/04 15:16:31  seletz
+ * - merged from linux_2_4_13_ac5_rmk2
+ *
+ * Revision 1.1.4.2  2001/11/19 17:18:57  seletz
+ * - more code cleanups
+ *
+ * Revision 1.1.4.1  2001/11/16 13:52:05  seletz
+ * - PT Digital Board Support Code
+ *
+ * Revision 1.1.2.2  2001/11/05 16:46:18  seletz
+ * - cleanups
+ *
+ * Revision 1.1.2.1  2001/10/15 16:00:43  seletz
+ * - first revision working with new board
+ *
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/tty.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/cpufreq.h>
+
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/irq.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/serial_sa1100.h>
+
+#include <asm/arch/irq.h>
+
+#include <linux/serial_core.h>
+
+#include "generic.h"
+#include "sa1111.h"
+
+#define DEBUG 1
+
+#ifdef DEBUG
+#	define DPRINTK( x, args... )	printk( "%s: line %d: "x, __FUNCTION__, __LINE__, ## args  );
+#else
+#	define DPRINTK( x, args... )	/* nix */
+#endif
+
+/**********************************************************************
+ *  prototypes
+ */
+
+/* init funcs */
+static void __init fixup_system3(struct machine_desc *desc,
+		struct param_struct *params, char **cmdline, struct meminfo *mi);
+static void __init get_system3_scr(void);
+static int __init system3_init(void);
+static void __init system3_init_irq(void);
+static void __init system3_map_io(void);
+
+static void system3_IRQ_demux( int irq, void *dev_id, struct pt_regs *regs );
+static int system3_get_mctrl(struct uart_port *port);
+static void system3_set_mctrl(struct uart_port *port, u_int mctrl);
+static void system3_uart_pm(struct uart_port *port, u_int state, u_int oldstate);
+static int sdram_notifier(struct notifier_block *nb, unsigned long event, void *data);
+
+extern void convert_to_tag_list(struct param_struct *params, int mem_init);
+
+
+/**********************************************************************
+ *  global data
+ */
+
+/**********************************************************************
+ *  static data
+ */
+
+static struct map_desc system3_io_desc[] __initdata = {
+ /* virtual     physical    length      domain     r  w  c  b */
+  { 0xe8000000, 0x00000000, 0x01000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 0 */
+  { 0xf3000000, 0x10000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* System Registers */
+  { 0xf4000000, 0x40000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* SA-1111 */
+  LAST_DESC
+};
+
+static struct sa1100_port_fns system3_port_fns __initdata = {
+	set_mctrl:	system3_set_mctrl,
+	get_mctrl:	system3_get_mctrl,
+	pm:		system3_uart_pm,
+};
+
+static struct irqaction system3_irq = {
+	name:		"PT Digital Board SA1111 IRQ",
+	handler:	system3_IRQ_demux,
+	flags:		SA_INTERRUPT
+};
+
+static struct notifier_block system3_clkchg_block = {
+	notifier_call:	sdram_notifier,
+};
+
+/**********************************************************************
+ *  Static functions
+ */
+
+static void __init system3_map_io(void)
+{
+	DPRINTK( "%s\n", "START" );
+	sa1100_map_io();
+	iotable_init(system3_io_desc);
+
+	sa1100_register_uart_fns(&system3_port_fns);
+	sa1100_register_uart(0, 1);	/* com port */
+	sa1100_register_uart(1, 2);
+	sa1100_register_uart(2, 3);	/* radio module */
+
+	Ser1SDCR0 |= SDCR0_SUS;
+}
+
+
+/*********************************************************************
+ * Install IRQ handler
+ */
+static void system3_IRQ_demux( int irq, void *dev_id, struct pt_regs *regs )
+{
+	u_char irr;
+
+	for(;;){
+		//irr = PTCPLD_REG_IRQSR & (PT_IRQ_LAN | PT_IRQ_USAR | PT_IRQ_SA1111);
+		irr = PT_IRQSR & (PT_IRQ_LAN | PT_IRQ_SA1111);
+
+		irr ^= (PT_IRQ_LAN);
+		if (!irr) break;
+
+		if( irr & PT_IRQ_LAN )
+			do_IRQ(IRQ_SYSTEM3_SMC9196, regs);
+
+#if 0
+		/* Highspeed Serial Bus not yet used */
+		if( irr & PT_IRQ_USAR )
+			do_IRQ(PT_USAR_IRQ, regs);
+#endif
+
+		if( irr & PT_IRQ_SA1111 )
+			sa1111_IRQ_demux(irq, dev_id, regs);
+	}
+}
+
+
+static void __init system3_init_irq(void)
+{
+	int irq;
+
+	DPRINTK( "%s\n", "START" );
+
+	/* SA1111 IRQ not routed to a GPIO. */
+	sa1111_init_irq(-1);
+
+	/* setup extra IRQs */
+	irq = IRQ_SYSTEM3_SMC9196;
+	irq_desc[irq].valid	= 1;
+	irq_desc[irq].probe_ok	= 1;
+
+#if 0
+	/* Highspeed Serial Bus not yet used */
+	irq = PT_USAR_IRQ;
+	irq_desc[irq].valid	= 1;
+	irq_desc[irq].probe_ok	= 1;
+#endif
+
+	/* IRQ by CPLD */
+	set_GPIO_IRQ_edge( GPIO_GPIO(25), GPIO_RISING_EDGE );
+	setup_arm_irq( IRQ_GPIO25, &system3_irq );
+}
+
+/**********************************************************************
+ * On system 3 limit cpu frequency to 206 Mhz
+ */
+static int sdram_notifier(struct notifier_block *nb, unsigned long event,
+		void *data)
+{
+	switch (event) {
+		case CPUFREQ_MINMAX:
+			cpufreq_updateminmax(data, 147500, 206000);
+			break;
+
+	}
+	return 0;
+}
+
+/**
+ *	fixup_system3 - fixup function for system 3 board
+ *	@desc:		machine description
+ *	@param:		kernel params
+ *	@cmdline:	kernel cmdline
+ *	@mi:		memory info struct
+ *
+ */
+static void __init fixup_system3(struct machine_desc *desc,
+		struct param_struct *params, char **cmdline, struct meminfo *mi)
+{
+	DPRINTK( "%s\n", "START" );
+
+	ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+	setup_ramdisk( 1, 0, 0, 8192 );
+	setup_initrd( 0xc0800000, 8*1024*1024 );
+}
+
+
+/**
+ *	system3_uart_pm - powermgmt callback function for system 3 UART
+ *	@port: uart port structure
+ *	@state: pm state
+ *	@oldstate: old pm state
+ *
+ */
+static void system3_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
+{
+	/* TODO: switch on/off uart in powersave mode */
+}
+
+/*
+ * Note! this can be called from IRQ context.
+ * FIXME: Handle PT Digital Board CTRL regs irq-safe.
+ *
+ * NB: system3 uses COM_RTS and COM_DTR for both UART1 (com port)
+ * and UART3 (radio module).  We only handle them for UART1 here.
+ */
+static void system3_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+	if (port->mapbase == _Ser1UTCR0) {
+		u_int set = 0, clear = 0;
+
+		if (mctrl & TIOCM_RTS)
+			set |= PT_CTRL2_RS1_RTS;
+		else
+			clear |= PT_CTRL2_RS1_RTS;
+
+		if (mctrl & TIOCM_DTR)
+			set |= PT_CTRL2_RS1_DTR;
+		else
+			clear |= PT_CTRL2_RS1_DTR;
+
+		PTCTRL2_clear(clear);
+		PTCTRL2_set(set);
+	}
+}
+
+static int system3_get_mctrl(struct uart_port *port)
+{
+	u_int ret = 0;
+	u_int irqsr = PT_IRQSR;
+
+	/* need 2 reads to read current value */
+	irqsr = PT_IRQSR;
+
+	/* TODO: check IRQ source register for modem/com
+	 status lines and set them correctly. */
+
+	ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
+
+	return ret;
+}
+
+static int __init system3_init(void)
+{
+	int ret = 0;
+	DPRINTK( "%s\n", "START" );
+
+	if ( !machine_is_pt_system3() ) {
+		ret = -EINVAL;
+		goto DONE;
+	}
+
+	/* init control register */
+	PT_CTRL0 = PT_CTRL0_INIT;
+	PT_CTRL1 = 0x02;
+	PT_CTRL2 = 0x00;
+	DPRINTK( "CTRL[0]=0x%02x\n", PT_CTRL0 );
+	DPRINTK( "CTRL[1]=0x%02x\n", PT_CTRL1 );
+	DPRINTK( "CTRL[2]=0x%02x\n", PT_CTRL2 );
+
+	/*
+	 * Ensure that the memory bus request/grant signals are setup,
+	 * and the grant is held in its inactive state.
+	 */
+	sa1110_mb_disable();
+
+	/*
+	 * Probe for a SA1111.
+	 */
+	ret = sa1111_probe(PT_SA1111_BASE);
+	if (ret < 0) {
+		printk( KERN_WARNING"PT Digital Board: no SA1111 found!\n" );
+		goto DONE;
+	}
+
+	/*
+	 * We found it.  Wake the chip up.
+	 */
+	sa1111_wake();
+
+	/*
+	 * The SDRAM configuration of the SA1110 and the SA1111 must
+	 * match.  This is very important to ensure that SA1111 accesses
+	 * don't corrupt the SDRAM.  Note that this ungates the SA1111's
+	 * MBGNT signal, so we must have called sa1110_mb_disable()
+	 * beforehand.
+	 */
+	sa1111_configure_smc(1,
+			     FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
+			     FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
+
+	/*
+	 * We only need to turn on DCLK whenever we want to use the
+	 * DMA.  It can otherwise be held firmly in the off position.
+	 */
+	SKPCR |= SKPCR_DCLKEN;
+
+	/*
+	 * Enable the SA1110 memory bus request and grant signals.
+	 */
+	sa1110_mb_enable();
+
+	system3_init_irq();
+
+#if defined( CONFIG_CPU_FREQ )
+	ret = cpufreq_register_notifier(&system3_clkchg_block);
+	if ( ret != 0 ) {
+		printk( KERN_WARNING"PT Digital Board: could not register clock scale callback\n" );
+		goto DONE;
+	}
+#endif
+
+	ret = 0;
+DONE:
+	DPRINTK( "ret=%d\n", ret );
+	return ret;
+}
+
+/**********************************************************************
+ *  Exported Functions
+ */
+
+/**********************************************************************
+ *  kernel magic macros
+ */
+__initcall(system3_init);
+
+MACHINE_START(PT_SYSTEM3, "PT System 3")
+	BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+	BOOT_PARAMS(0xc0000100)
+	FIXUP(fixup_system3)
+	MAPIO(system3_map_io)
+	INITIRQ(sa1100_init_irq)
+MACHINE_END
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/victor.c linux/arch/arm/mach-sa1100/victor.c
--- linux.orig/arch/arm/mach-sa1100/victor.c	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/mach-sa1100/victor.c	Tue May 28 22:39:14 2002
@@ -60,7 +60,7 @@
 
 static struct map_desc victor_io_desc[] __initdata = {
  /* virtual     physical    length      domain     r  w  c  b */
-  { 0xe8000000, 0x00000000, 0x00200000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash */
+  { 0xe8000000, 0x00000000, 0x00200000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash */
   LAST_DESC
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/xp860.c linux/arch/arm/mach-sa1100/xp860.c
--- linux.orig/arch/arm/mach-sa1100/xp860.c	Thu Oct 11 16:04:57 2001
+++ linux/arch/arm/mach-sa1100/xp860.c	Tue May 28 22:39:27 2002
@@ -21,6 +21,7 @@
 
 static void xp860_power_off(void)
 {
+	cli();
 	GPDR |= GPIO_GPIO20;
 	GPSR = GPIO_GPIO20;
 	mdelay(1000);
@@ -40,7 +41,7 @@
 	/*
 	 * Probe for SA1111.
 	 */
-	ret = sa1111_probe();
+	ret = sa1111_probe(0x40000000);
 	if (ret < 0)
 		return ret;
 
@@ -65,9 +66,9 @@
 
 static struct map_desc xp860_io_desc[] __initdata = {
  /* virtual     physical    length      domain     r  w  c  b */
-  { 0xf0000000, 0x10000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* SCSI */
-  { 0xf1000000, 0x18000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* LAN */
-  { 0xf4000000, 0x40000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* SA-1111 */
+  { 0xf0000000, 0x10000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* SCSI */
+  { 0xf1000000, 0x18000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* LAN */
+  { 0xf4000000, 0x40000000, 0x00800000, DOMAIN_IO, 0, 1, 0, 0 }, /* SA-1111 */
   LAST_DESC
 };
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mach-sa1100/yopy.c linux/arch/arm/mach-sa1100/yopy.c
--- linux.orig/arch/arm/mach-sa1100/yopy.c	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/mach-sa1100/yopy.c	Tue May 28 22:39:16 2002
@@ -1,8 +1,6 @@
 /*
  * linux/arch/arm/mach-sa1100/yopy.c
  */
-
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -52,14 +50,16 @@
 
 static int __init yopy_hw_init(void)
 {
-	YOPY_EGPIO = yopy_egpio;
+	if (machine_is_yopy()) {
+		YOPY_EGPIO = yopy_egpio;
 
-	/* Enable Output */
-	PPDR |= PPC_L_BIAS;
-	PSDR &= ~PPC_L_BIAS;
-	PPSR |= PPC_L_BIAS;
+		/* Enable Output */
+		PPDR |= PPC_L_BIAS;
+		PSDR &= ~PPC_L_BIAS;
+		PPSR |= PPC_L_BIAS;
 
-	YOPY_EGPIO = yopy_egpio;
+		YOPY_EGPIO = yopy_egpio;
+	}
 
 	return 0;
 }
@@ -69,9 +69,9 @@
 
 static struct map_desc yopy_io_desc[] __initdata = {
  /* virtual     physical    length      domain     r  w  c  b */
-  { 0xe8000000, 0x00000000, 0x04000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash 0 */
-  { 0xec000000, 0x08000000, 0x04000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash 1 */
-  { 0xf0000000, 0x48000000, 0x00300000, DOMAIN_IO, 1, 1, 0, 0 }, /* LCD */
+  { 0xe8000000, 0x00000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash 0 */
+  { 0xec000000, 0x08000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash 1 */
+  { 0xf0000000, 0x48000000, 0x00300000, DOMAIN_IO, 0, 1, 0, 0 }, /* LCD */
   { 0xf1000000, 0x10000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* EGPIO */
   LAST_DESC
 };
@@ -82,6 +82,8 @@
 	iotable_init(yopy_io_desc);
 
 	sa1100_register_uart(0, 3);
+
+	set_GPIO_IRQ_edge(GPIO_UCB1200_IRQ, GPIO_RISING_EDGE);
 }
 
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mm/Makefile linux/arch/arm/mm/Makefile
--- linux.orig/arch/arm/mm/Makefile	Fri Nov  9 21:58:02 2001
+++ linux/arch/arm/mm/Makefile	Tue May 28 22:39:28 2002
@@ -13,19 +13,20 @@
 
 # Object file lists.
 
-obj-y		:= init.o
+obj-y		:= init.o extable.o fault-common.o
 obj-m		:=
 obj-n		:=
 obj-		:=
 export-objs	:= proc-syms.o discontig.o
 
-cpu32-y		:= consistent.o fault-armv.o ioremap.o mm-armv.o
-cpu32-$(CONFIG_MODULES) += proc-syms.o
+ifeq ($(CONFIG_CPU_32),y)
+obj-y		+= consistent.o fault-armv.o ioremap.o mm-armv.o
+obj-$(CONFIG_MODULES) += proc-syms.o
+endif
 
-obj-y		+= extable.o fault-common.o
 obj-$(CONFIG_CPU_26) += fault-armo.o mm-armo.o small_page.o
-obj-$(CONFIG_CPU_32) += $(cpu32-y)
 
+obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o
 obj-$(CONFIG_DISCONTIGMEM) += discontig.o
 
 # Select the processor-specific files
@@ -34,6 +35,7 @@
 p-$(CONFIG_CPU_ARM710)	+= proc-arm6,7.o
 p-$(CONFIG_CPU_ARM720T)	+= proc-arm720.o
 p-$(CONFIG_CPU_ARM920T)	+= proc-arm920.o
+p-$(CONFIG_CPU_ARM922T)	+= proc-arm922.o
 p-$(CONFIG_CPU_ARM926T)	+= proc-arm926.o
 p-$(CONFIG_CPU_ARM1020)	+= proc-arm1020.o
 p-$(CONFIG_CPU_SA110)	+= proc-sa110.o
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mm/alignment.c linux/arch/arm/mm/alignment.c
--- linux.orig/arch/arm/mm/alignment.c	Thu Jan  1 00:00:00 1970
+++ linux/arch/arm/mm/alignment.c	Tue May 28 22:39:27 2002
@@ -0,0 +1,609 @@
+/*
+ *  linux/arch/arm/mm/alignment.c
+ *
+ *  Copyright (C) 1995  Linus Torvalds
+ *  Modifications for ARM processor (c) 1995-2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/config.h>
+#include <linux/compiler.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/proc_fs.h>
+#include <linux/bitops.h>
+#include <linux/init.h>
+
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+#include <asm/unaligned.h>
+
+extern void
+do_bad_area(struct task_struct *tsk, struct mm_struct *mm, unsigned long addr,
+	    int error_code, struct pt_regs *regs);
+
+/*
+ * 32-bit misaligned trap handler (c) 1998 San Mehat (CCC) -July 1998
+ * /proc/sys/debug/alignment, modified and integrated into
+ * Linux 2.1 by Russell King
+ *
+ * Speed optimisations and better fault handling by Russell King.
+ *
+ * *** NOTE ***
+ * This code is not portable to processors with late data abort handling.
+ */
+#define CODING_BITS(i)	(i & 0x0e000000)
+
+#define LDST_I_BIT(i)	(i & (1 << 26))		/* Immediate constant	*/
+#define LDST_P_BIT(i)	(i & (1 << 24))		/* Preindex		*/
+#define LDST_U_BIT(i)	(i & (1 << 23))		/* Add offset		*/
+#define LDST_W_BIT(i)	(i & (1 << 21))		/* Writeback		*/
+#define LDST_L_BIT(i)	(i & (1 << 20))		/* Load			*/
+
+#define LDST_P_EQ_U(i)	((((i) ^ ((i) >> 1)) & (1 << 23)) == 0)
+
+#define LDSTH_I_BIT(i)	(i & (1 << 22))		/* half-word immed	*/
+#define LDM_S_BIT(i)	(i & (1 << 22))		/* write CPSR from SPSR	*/
+
+#define RN_BITS(i)	((i >> 16) & 15)	/* Rn			*/
+#define RD_BITS(i)	((i >> 12) & 15)	/* Rd			*/
+#define RM_BITS(i)	(i & 15)		/* Rm			*/
+
+#define REGMASK_BITS(i)	(i & 0xffff)
+#define OFFSET_BITS(i)	(i & 0x0fff)
+
+#define IS_SHIFT(i)	(i & 0x0ff0)
+#define SHIFT_BITS(i)	((i >> 7) & 0x1f)
+#define SHIFT_TYPE(i)	(i & 0x60)
+#define SHIFT_LSL	0x00
+#define SHIFT_LSR	0x20
+#define SHIFT_ASR	0x40
+#define SHIFT_RORRRX	0x60
+
+static unsigned long ai_user;
+static unsigned long ai_sys;
+static unsigned long ai_skipped;
+static unsigned long ai_half;
+static unsigned long ai_word;
+static unsigned long ai_multi;
+static int ai_usermode;
+
+#ifdef CONFIG_PROC_FS
+static const char *usermode_action[] = {
+	"ignored",
+	"warn",
+	"fixup",
+	"fixup+warn",
+	"signal",
+	"signal+warn"
+};
+
+static int
+proc_alignment_read(char *page, char **start, off_t off, int count, int *eof,
+		    void *data)
+{
+	char *p = page;
+	int len;
+
+	p += sprintf(p, "User:\t\t%lu\n", ai_user);
+	p += sprintf(p, "System:\t\t%lu\n", ai_sys);
+	p += sprintf(p, "Skipped:\t%lu\n", ai_skipped);
+	p += sprintf(p, "Half:\t\t%lu\n", ai_half);
+	p += sprintf(p, "Word:\t\t%lu\n", ai_word);
+	p += sprintf(p, "Multi:\t\t%lu\n", ai_multi);
+	p += sprintf(p, "User faults:\t%i (%s)\n", ai_usermode,
+			usermode_action[ai_usermode]);
+
+	len = (p - page) - off;
+	if (len < 0)
+		len = 0;
+
+	*eof = (len <= count) ? 1 : 0;
+	*start = page + off;
+
+	return len;
+}
+
+static int proc_alignment_write(struct file *file, const char *buffer,
+			       unsigned long count, void *data)
+{
+	int mode;
+
+	if (count > 0) {
+		if (get_user(mode, buffer))
+			return -EFAULT;
+		if (mode >= '0' && mode <= '5')
+			   ai_usermode = mode - '0';
+	}
+	return count;
+}
+
+/*
+ * This needs to be done after sysctl_init, otherwise sys/ will be
+ * overwritten.  Actually, this shouldn't be in sys/ at all since
+ * it isn't a sysctl, and it doesn't contain sysctl information.
+ * We now locate it in /proc/cpu/alignment instead.
+ */
+static int __init alignment_init(void)
+{
+	struct proc_dir_entry *res;
+
+	res = proc_mkdir("cpu", NULL);
+	if (!res)
+		return -ENOMEM;
+
+	res = create_proc_entry("alignment", S_IWUSR | S_IRUGO, res);
+	if (!res)
+		return -ENOMEM;
+
+	res->read_proc = proc_alignment_read;
+	res->write_proc = proc_alignment_write;
+
+	return 0;
+}
+
+__initcall(alignment_init);
+#endif /* CONFIG_PROC_FS */
+
+union offset_union {
+	unsigned long un;
+	  signed long sn;
+};
+
+#define TYPE_ERROR	0
+#define TYPE_FAULT	1
+#define TYPE_LDST	2
+#define TYPE_DONE	3
+
+#define __get8_unaligned_check(ins,val,addr,err)	\
+	__asm__(					\
+	"1:	"ins"	%1, [%2], #1\n"			\
+	"2:\n"						\
+	"	.section .fixup,\"ax\"\n"		\
+	"	.align	2\n"				\
+	"3:	mov	%0, #1\n"			\
+	"	b	2b\n"				\
+	"	.previous\n"				\
+	"	.section __ex_table,\"a\"\n"		\
+	"	.align	3\n"				\
+	"	.long	1b, 3b\n"			\
+	"	.previous\n"				\
+	: "=r" (err), "=&r" (val), "=r" (addr)		\
+	: "0" (err), "2" (addr))
+
+#define __get16_unaligned_check(ins,val,addr)			\
+	do {							\
+		unsigned int err = 0, v, a = addr;		\
+		__get8_unaligned_check(ins,val,a,err);		\
+		__get8_unaligned_check(ins,v,a,err);		\
+		val |= v << 8;					\
+		if (err)					\
+			goto fault;				\
+	} while (0)
+
+#define get16_unaligned_check(val,addr) \
+	__get16_unaligned_check("ldrb",val,addr)
+
+#define get16t_unaligned_check(val,addr) \
+	__get16_unaligned_check("ldrbt",val,addr)
+
+#define __get32_unaligned_check(ins,val,addr)			\
+	do {							\
+		unsigned int err = 0, v, a = addr;		\
+		__get8_unaligned_check(ins,val,a,err);		\
+		__get8_unaligned_check(ins,v,a,err);		\
+		val |= v << 8;					\
+		__get8_unaligned_check(ins,v,a,err);		\
+		val |= v << 16;					\
+		__get8_unaligned_check(ins,v,a,err);		\
+		val |= v << 24;					\
+		if (err)					\
+			goto fault;				\
+	} while (0)
+
+#define get32_unaligned_check(val,addr) \
+	__get32_unaligned_check("ldrb",val,addr)
+
+#define get32t_unaligned_check(val,addr) \
+	__get32_unaligned_check("ldrbt",val,addr)
+
+#define __put16_unaligned_check(ins,val,addr)			\
+	do {							\
+		unsigned int err = 0, v = val, a = addr;	\
+		__asm__(					\
+		"1:	"ins"	%1, [%2], #1\n"			\
+		"	mov	%1, %1, lsr #8\n"		\
+		"2:	"ins"	%1, [%2]\n"			\
+		"3:\n"						\
+		"	.section .fixup,\"ax\"\n"		\
+		"	.align	2\n"				\
+		"4:	mov	%0, #1\n"			\
+		"	b	3b\n"				\
+		"	.previous\n"				\
+		"	.section __ex_table,\"a\"\n"		\
+		"	.align	3\n"				\
+		"	.long	1b, 4b\n"			\
+		"	.long	2b, 4b\n"			\
+		"	.previous\n"				\
+		: "=r" (err), "=&r" (v), "=&r" (a)		\
+		: "0" (err), "1" (v), "2" (a));			\
+		if (err)					\
+			goto fault;				\
+	} while (0)
+
+#define put16_unaligned_check(val,addr)  \
+	__put16_unaligned_check("strb",val,addr)
+
+#define put16t_unaligned_check(val,addr) \
+	__put16_unaligned_check("strbt",val,addr)
+
+#define __put32_unaligned_check(ins,val,addr)			\
+	do {							\
+		unsigned int err = 0, v = val, a = addr;	\
+		__asm__(					\
+		"1:	"ins"	%1, [%2], #1\n"			\
+		"	mov	%1, %1, lsr #8\n"		\
+		"2:	"ins"	%1, [%2], #1\n"			\
+		"	mov	%1, %1, lsr #8\n"		\
+		"3:	"ins"	%1, [%2], #1\n"			\
+		"	mov	%1, %1, lsr #8\n"		\
+		"4:	"ins"	%1, [%2]\n"			\
+		"5:\n"						\
+		"	.section .fixup,\"ax\"\n"		\
+		"	.align	2\n"				\
+		"6:	mov	%0, #1\n"			\
+		"	b	5b\n"				\
+		"	.previous\n"				\
+		"	.section __ex_table,\"a\"\n"		\
+		"	.align	3\n"				\
+		"	.long	1b, 6b\n"			\
+		"	.long	2b, 6b\n"			\
+		"	.long	3b, 6b\n"			\
+		"	.long	4b, 6b\n"			\
+		"	.previous\n"				\
+		: "=r" (err), "=&r" (v), "=&r" (a)		\
+		: "0" (err), "1" (v), "2" (a));			\
+		if (err)					\
+			goto fault;				\
+	} while (0)
+
+#define put32_unaligned_check(val,addr)	 \
+	__put32_unaligned_check("strb", val, addr)
+
+#define put32t_unaligned_check(val,addr) \
+	__put32_unaligned_check("strbt", val, addr)
+
+static void
+do_alignment_finish_ldst(unsigned long addr, unsigned long instr, struct pt_regs *regs, union offset_union offset)
+{
+	if (!LDST_U_BIT(instr))
+		offset.un = -offset.un;
+
+	if (!LDST_P_BIT(instr))
+		addr += offset.un;
+
+	if (!LDST_P_BIT(instr) || LDST_W_BIT(instr))
+		regs->uregs[RN_BITS(instr)] = addr;
+}
+
+static int
+do_alignment_ldrhstrh(unsigned long addr, unsigned long instr, struct pt_regs *regs)
+{
+	unsigned int rd = RD_BITS(instr);
+
+	if ((instr & 0x01f00ff0) == 0x01000090)
+		goto swp;
+
+	if ((instr & 0x90) != 0x90 || (instr & 0x60) == 0)
+		goto bad;
+
+	ai_half += 1;
+
+	if (user_mode(regs))
+		goto user;
+
+	if (LDST_L_BIT(instr)) {
+		unsigned long val;
+		get16_unaligned_check(val, addr);
+
+		/* signed half-word? */
+		if (instr & 0x40)
+			val = (signed long)((signed short) val);
+
+		regs->uregs[rd] = val;
+	} else
+		put16_unaligned_check(regs->uregs[rd], addr);
+
+	return TYPE_LDST;
+
+ user:
+ 	if (LDST_L_BIT(instr)) {
+ 		unsigned long val;
+ 		get16t_unaligned_check(val, addr);
+
+ 		/* signed half-word? */
+ 		if (instr & 0x40)
+ 			val = (signed long)((signed short) val);
+
+ 		regs->uregs[rd] = val;
+ 	} else
+ 		put16t_unaligned_check(regs->uregs[rd], addr);
+
+ 	return TYPE_LDST;
+
+ swp:
+	printk(KERN_ERR "Alignment trap: not handling swp instruction\n");
+ bad:
+	return TYPE_ERROR;
+
+ fault:
+	return TYPE_FAULT;
+}
+
+static int
+do_alignment_ldrstr(unsigned long addr, unsigned long instr, struct pt_regs *regs)
+{
+	unsigned int rd = RD_BITS(instr);
+
+	ai_word += 1;
+
+	if ((!LDST_P_BIT(instr) && LDST_W_BIT(instr)) || user_mode(regs))
+		goto trans;
+
+	if (LDST_L_BIT(instr)) {
+		unsigned int val;
+		get32_unaligned_check(val, addr);
+		regs->uregs[rd] = val;
+	} else
+		put32_unaligned_check(regs->uregs[rd], addr);
+	return TYPE_LDST;
+
+ trans:
+	if (LDST_L_BIT(instr)) {
+		unsigned int val;
+		get32t_unaligned_check(val, addr);
+		regs->uregs[rd] = val;
+	} else
+		put32t_unaligned_check(regs->uregs[rd], addr);
+	return TYPE_LDST;
+
+ fault:
+	return TYPE_FAULT;
+}
+
+/*
+ * LDM/STM alignment handler.
+ *
+ * There are 4 variants of this instruction:
+ *
+ * B = rn pointer before instruction, A = rn pointer after instruction
+ *              ------ increasing address ----->
+ *	        |    | r0 | r1 | ... | rx |    |
+ * PU = 01             B                    A
+ * PU = 11        B                    A
+ * PU = 00        A                    B
+ * PU = 10             A                    B
+ */
+static int
+do_alignment_ldmstm(unsigned long addr, unsigned long instr, struct pt_regs *regs)
+{
+	unsigned int rd, rn, correction, nr_regs, regbits;
+	unsigned long eaddr, newaddr;
+
+	if (LDM_S_BIT(instr))
+		goto bad;
+
+	correction = 4; /* processor implementation defined */
+	regs->ARM_pc += correction;
+
+	ai_multi += 1;
+
+	/* count the number of registers in the mask to be transferred */
+	nr_regs = hweight16(REGMASK_BITS(instr)) * 4;
+
+	rn = RN_BITS(instr);
+	newaddr = eaddr = regs->uregs[rn];
+
+	if (!LDST_U_BIT(instr))
+		nr_regs = -nr_regs;
+	newaddr += nr_regs;
+	if (!LDST_U_BIT(instr))
+		eaddr = newaddr;
+
+	if (LDST_P_EQ_U(instr))	/* U = P */
+		eaddr += 4;
+
+	/* 
+	 * For alignment faults on the ARM922T the MMU  makes 
+	 * the FSR (and hence addr) equal to the updated base address
+	 * of the multiple access rather than the restored value.
+	 * Switch this messsage off if we've got a ARM922, otherwise
+	 * [ls]dm alignment faults are noisy!
+	 */
+#if !(defined CONFIG_CPU_ARM922T)  
+	/*
+	 * This is a "hint" - we already have eaddr worked out by the
+	 * processor for us.
+	 */
+	if (addr != eaddr) {
+		printk(KERN_ERR "LDMSTM: PC = %08lx, instr = %08lx, "
+			"addr = %08lx, eaddr = %08lx\n",
+			 instruction_pointer(regs), instr, addr, eaddr);
+		show_regs(regs);
+	}
+#endif
+
+	if (user_mode(regs)) {
+		for (regbits = REGMASK_BITS(instr), rd = 0; regbits;
+		     regbits >>= 1, rd += 1)
+			if (regbits & 1) {
+				if (LDST_L_BIT(instr)) {
+					unsigned int val;
+					get32t_unaligned_check(val, eaddr);
+					regs->uregs[rd] = val;
+				} else
+					put32t_unaligned_check(regs->uregs[rd], eaddr);
+				eaddr += 4;
+			}
+	} else {
+		for (regbits = REGMASK_BITS(instr), rd = 0; regbits;
+		     regbits >>= 1, rd += 1)
+			if (regbits & 1) {
+				if (LDST_L_BIT(instr)) {
+					unsigned int val;
+					get32_unaligned_check(val, eaddr);
+					regs->uregs[rd] = val;
+				} else
+					put32_unaligned_check(regs->uregs[rd], eaddr);
+				eaddr += 4;
+			}
+	}
+
+	if (LDST_W_BIT(instr))
+		regs->uregs[rn] = newaddr;
+	if (!LDST_L_BIT(instr) || !(REGMASK_BITS(instr) & (1 << 15)))
+		regs->ARM_pc -= correction;
+	return TYPE_DONE;
+
+fault:
+	regs->ARM_pc -= correction;
+	return TYPE_FAULT;
+
+bad:
+	printk(KERN_ERR "Alignment trap: not handling ldm with s-bit set\n");
+	return TYPE_ERROR;
+}
+
+int do_alignment(unsigned long addr, int error_code, struct pt_regs *regs)
+{
+	union offset_union offset;
+	unsigned long instr, instrptr;
+	int (*handler)(unsigned long addr, unsigned long instr, struct pt_regs *regs);
+	unsigned int type;
+
+	instrptr = instruction_pointer(regs);
+	instr = *(unsigned long *)instrptr;
+
+	if (user_mode(regs))
+		goto user;
+
+	ai_sys += 1;
+
+ fixup:
+
+	regs->ARM_pc += 4;
+
+	switch (CODING_BITS(instr)) {
+	case 0x00000000:	/* ldrh or strh */
+		if (LDSTH_I_BIT(instr))
+			offset.un = (instr & 0xf00) >> 4 | (instr & 15);
+		else
+			offset.un = regs->uregs[RM_BITS(instr)];
+		handler = do_alignment_ldrhstrh;
+		break;
+
+	case 0x04000000:	/* ldr or str immediate */
+		offset.un = OFFSET_BITS(instr);
+		handler = do_alignment_ldrstr;
+		break;
+
+	case 0x06000000:	/* ldr or str register */
+		offset.un = regs->uregs[RM_BITS(instr)];
+
+		if (IS_SHIFT(instr)) {
+			unsigned int shiftval = SHIFT_BITS(instr);
+
+			switch(SHIFT_TYPE(instr)) {
+			case SHIFT_LSL:
+				offset.un <<= shiftval;
+				break;
+
+			case SHIFT_LSR:
+				offset.un >>= shiftval;
+				break;
+
+			case SHIFT_ASR:
+				offset.sn >>= shiftval;
+				break;
+
+			case SHIFT_RORRRX:
+				if (shiftval == 0) {
+					offset.un >>= 1;
+					if (regs->ARM_cpsr & CC_C_BIT)
+						offset.un |= 1 << 31;
+				} else
+					offset.un = offset.un >> shiftval |
+							  offset.un << (32 - shiftval);
+				break;
+			}
+		}
+		handler = do_alignment_ldrstr;
+		break;
+
+	case 0x08000000:	/* ldm or stm */
+		handler = do_alignment_ldmstm;
+		break;
+
+	default:
+		goto bad;
+	}
+
+	type = handler(addr, instr, regs);
+
+	if (type == TYPE_ERROR || type == TYPE_FAULT)
+		goto bad_or_fault;
+
+	if (type == TYPE_LDST)
+		do_alignment_finish_ldst(addr, instr, regs, offset);
+
+	return 0;
+
+ bad_or_fault:
+	if (type == TYPE_ERROR)
+		goto bad;
+	regs->ARM_pc -= 4;
+	/*
+	 * We got a fault - fix it up, or die.
+	 */
+	do_bad_area(current, current->mm, addr, error_code, regs);
+	return 0;
+
+ bad:
+	/*
+	 * Oops, we didn't handle the instruction.
+	 */
+	printk(KERN_ERR "Alignment trap: not handling instruction "
+		"%08lx at [<%08lx>]\n", instr, instrptr);
+	ai_skipped += 1;
+	return 1;
+
+ user:
+	ai_user += 1;
+
+	if (ai_usermode & 1)
+		printk("Alignment trap: %s (%d) PC=0x%08lx Instr=0x%08lx "
+		       "Address=0x%08lx Code 0x%02x\n", current->comm,
+			current->pid, instrptr, instr, addr, error_code);
+
+	if (ai_usermode & 2)
+		goto fixup;
+
+	if (ai_usermode & 4)
+		force_sig(SIGBUS, current);
+	else
+		set_cr(cr_no_alignment);
+
+	return 0;
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mm/fault-armv.c linux/arch/arm/mm/fault-armv.c
--- linux.orig/arch/arm/mm/fault-armv.c	Thu Oct 25 20:53:46 2001
+++ linux/arch/arm/mm/fault-armv.c	Tue May 28 22:39:19 2002
@@ -27,7 +27,6 @@
 #include <asm/uaccess.h>
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
-#include <asm/unaligned.h>
 
 extern void die_if_kernel(const char *str, struct pt_regs *regs, int err);
 extern void show_pte(struct mm_struct *mm, unsigned long addr);
@@ -40,499 +39,15 @@
 			struct pt_regs *regs);
 
 #ifdef CONFIG_ALIGNMENT_TRAP
-/*
- * 32-bit misaligned trap handler (c) 1998 San Mehat (CCC) -July 1998
- * /proc/sys/debug/alignment, modified and integrated into
- * Linux 2.1 by Russell King
- *
- * Speed optimisations and better fault handling by Russell King.
- *
- * *** NOTE ***
- * This code is not portable to processors with late data abort handling.
- */
-#define CODING_BITS(i)	(i & 0x0e000000)
-
-#define LDST_I_BIT(i)	(i & (1 << 26))		/* Immediate constant	*/
-#define LDST_P_BIT(i)	(i & (1 << 24))		/* Preindex		*/
-#define LDST_U_BIT(i)	(i & (1 << 23))		/* Add offset		*/
-#define LDST_W_BIT(i)	(i & (1 << 21))		/* Writeback		*/
-#define LDST_L_BIT(i)	(i & (1 << 20))		/* Load			*/
-
-#define LDST_P_EQ_U(i)	((((i) ^ ((i) >> 1)) & (1 << 23)) == 0)
-
-#define LDSTH_I_BIT(i)	(i & (1 << 22))		/* half-word immed	*/
-#define LDM_S_BIT(i)	(i & (1 << 22))		/* write CPSR from SPSR	*/
-
-#define RN_BITS(i)	((i >> 16) & 15)	/* Rn			*/
-#define RD_BITS(i)	((i >> 12) & 15)	/* Rd			*/
-#define RM_BITS(i)	(i & 15)		/* Rm			*/
-
-#define REGMASK_BITS(i)	(i & 0xffff)
-#define OFFSET_BITS(i)	(i & 0x0fff)
-
-#define IS_SHIFT(i)	(i & 0x0ff0)
-#define SHIFT_BITS(i)	((i >> 7) & 0x1f)
-#define SHIFT_TYPE(i)	(i & 0x60)
-#define SHIFT_LSL	0x00
-#define SHIFT_LSR	0x20
-#define SHIFT_ASR	0x40
-#define SHIFT_RORRRX	0x60
-
-static unsigned long ai_user;
-static unsigned long ai_sys;
-static unsigned long ai_skipped;
-static unsigned long ai_half;
-static unsigned long ai_word;
-static unsigned long ai_multi;
-
-#ifdef CONFIG_SYSCTL
-static int proc_alignment_read(char *page, char **start, off_t off,
-			       int count, int *eof, void *data)
-{
-	char *p = page;
-	int len;
-
-	p += sprintf(p, "User:\t\t%li\n", ai_user);
-	p += sprintf(p, "System:\t\t%li\n", ai_sys);
-	p += sprintf(p, "Skipped:\t%li\n", ai_skipped);
-	p += sprintf(p, "Half:\t\t%li\n", ai_half);
-	p += sprintf(p, "Word:\t\t%li\n", ai_word);
-	p += sprintf(p, "Multi:\t\t%li\n", ai_multi);
-
-	len = (p - page) - off;
-	if (len < 0)
-		len = 0;
-
-	*eof = (len <= count) ? 1 : 0;
-	*start = page + off;
-
-	return len;
-}
-
-/*
- * This needs to be done after sysctl_init, otherwise sys/
- * will be overwritten.
- */
-static int __init alignment_init(void)
-{
-	create_proc_read_entry("sys/debug/alignment", 0, NULL,
-				proc_alignment_read, NULL);
-	return 0;
-}
-
-__initcall(alignment_init);
-#endif /* CONFIG_SYSCTL */
-
-union offset_union {
-	unsigned long un;
-	  signed long sn;
-};
-
-#define TYPE_ERROR	0
-#define TYPE_FAULT	1
-#define TYPE_LDST	2
-#define TYPE_DONE	3
-
-#define get8_unaligned_check(val,addr,err)		\
-	__asm__(					\
-	"1:	ldrb	%1, [%2], #1\n"			\
-	"2:\n"						\
-	"	.section .fixup,\"ax\"\n"		\
-	"	.align	2\n"				\
-	"3:	mov	%0, #1\n"			\
-	"	b	2b\n"				\
-	"	.previous\n"				\
-	"	.section __ex_table,\"a\"\n"		\
-	"	.align	3\n"				\
-	"	.long	1b, 3b\n"			\
-	"	.previous\n"				\
-	: "=r" (err), "=&r" (val), "=r" (addr)		\
-	: "0" (err), "2" (addr))
-
-#define get8t_unaligned_check(val,addr,err)		\
-	__asm__(					\
-	"1:	ldrbt	%1, [%2], #1\n"			\
-	"2:\n"						\
-	"	.section .fixup,\"ax\"\n"		\
-	"	.align	2\n"				\
-	"3:	mov	%0, #1\n"			\
-	"	b	2b\n"				\
-	"	.previous\n"				\
-	"	.section __ex_table,\"a\"\n"		\
-	"	.align	3\n"				\
-	"	.long	1b, 3b\n"			\
-	"	.previous\n"				\
-	: "=r" (err), "=&r" (val), "=r" (addr)		\
-	: "0" (err), "2" (addr))
-
-#define get16_unaligned_check(val,addr)				\
-	do {							\
-		unsigned int err = 0, v, a = addr;		\
-		get8_unaligned_check(val,a,err);		\
-		get8_unaligned_check(v,a,err);			\
-		val |= v << 8;					\
-		if (err)					\
-			goto fault;				\
-	} while (0)
-
-#define put16_unaligned_check(val,addr)				\
-	do {							\
-		unsigned int err = 0, v = val, a = addr;	\
-		__asm__(					\
-		"1:	strb	%1, [%2], #1\n"			\
-		"	mov	%1, %1, lsr #8\n"		\
-		"2:	strb	%1, [%2]\n"			\
-		"3:\n"						\
-		"	.section .fixup,\"ax\"\n"		\
-		"	.align	2\n"				\
-		"4:	mov	%0, #1\n"			\
-		"	b	3b\n"				\
-		"	.previous\n"				\
-		"	.section __ex_table,\"a\"\n"		\
-		"	.align	3\n"				\
-		"	.long	1b, 4b\n"			\
-		"	.long	2b, 4b\n"			\
-		"	.previous\n"				\
-		: "=r" (err), "=&r" (v), "=&r" (a)		\
-		: "0" (err), "1" (v), "2" (a));			\
-		if (err)					\
-			goto fault;				\
-	} while (0)
-
-#define __put32_unaligned_check(ins,val,addr)			\
-	do {							\
-		unsigned int err = 0, v = val, a = addr;	\
-		__asm__(					\
-		"1:	"ins"	%1, [%2], #1\n"			\
-		"	mov	%1, %1, lsr #8\n"		\
-		"2:	"ins"	%1, [%2], #1\n"			\
-		"	mov	%1, %1, lsr #8\n"		\
-		"3:	"ins"	%1, [%2], #1\n"			\
-		"	mov	%1, %1, lsr #8\n"		\
-		"4:	"ins"	%1, [%2]\n"			\
-		"5:\n"						\
-		"	.section .fixup,\"ax\"\n"		\
-		"	.align	2\n"				\
-		"6:	mov	%0, #1\n"			\
-		"	b	5b\n"				\
-		"	.previous\n"				\
-		"	.section __ex_table,\"a\"\n"		\
-		"	.align	3\n"				\
-		"	.long	1b, 6b\n"			\
-		"	.long	2b, 6b\n"			\
-		"	.long	3b, 6b\n"			\
-		"	.long	4b, 6b\n"			\
-		"	.previous\n"				\
-		: "=r" (err), "=&r" (v), "=&r" (a)		\
-		: "0" (err), "1" (v), "2" (a));			\
-		if (err)					\
-			goto fault;				\
-	} while (0)
-
-#define get32_unaligned_check(val,addr)				\
-	do {							\
-		unsigned int err = 0, v, a = addr;		\
-		get8_unaligned_check(val,a,err);		\
-		get8_unaligned_check(v,a,err);			\
-		val |= v << 8;					\
-		get8_unaligned_check(v,a,err);			\
-		val |= v << 16;					\
-		get8_unaligned_check(v,a,err);			\
-		val |= v << 24;					\
-		if (err)					\
-			goto fault;				\
-	} while (0)
-
-#define put32_unaligned_check(val,addr)	 \
-	__put32_unaligned_check("strb", val, addr)
-
-#define get32t_unaligned_check(val,addr)			\
-	do {							\
-		unsigned int err = 0, v, a = addr;		\
-		get8t_unaligned_check(val,a,err);		\
-		get8t_unaligned_check(v,a,err);			\
-		val |= v << 8;					\
-		get8t_unaligned_check(v,a,err);			\
-		val |= v << 16;					\
-		get8t_unaligned_check(v,a,err);			\
-		val |= v << 24;					\
-		if (err)					\
-			goto fault;				\
-	} while (0)
-
-#define put32t_unaligned_check(val,addr) \
-	__put32_unaligned_check("strbt", val, addr)
-
-static void
-do_alignment_finish_ldst(unsigned long addr, unsigned long instr, struct pt_regs *regs, union offset_union offset)
-{
-	if (!LDST_U_BIT(instr))
-		offset.un = -offset.un;
-
-	if (!LDST_P_BIT(instr))
-		addr += offset.un;
-
-	if (!LDST_P_BIT(instr) || LDST_W_BIT(instr))
-		regs->uregs[RN_BITS(instr)] = addr;
-}
-
-static int
-do_alignment_ldrhstrh(unsigned long addr, unsigned long instr, struct pt_regs *regs)
-{
-	unsigned int rd = RD_BITS(instr);
-
-	if ((instr & 0x01f00ff0) == 0x01000090)
-		goto swp;
-
-	if ((instr & 0x90) != 0x90 || (instr & 0x60) == 0)
-		goto bad;
-
-	ai_half += 1;
-
-	if (LDST_L_BIT(instr)) {
-		unsigned long val;
-		get16_unaligned_check(val, addr);
-
-		/* signed half-word? */
-		if (instr & 0x40)
-			val = (signed long)((signed short) val);
-
-		regs->uregs[rd] = val;
-	} else
-		put16_unaligned_check(regs->uregs[rd], addr);
-
-	return TYPE_LDST;
-
-swp:
-	printk(KERN_ERR "Alignment trap: not handling swp instruction\n");
-bad:
-	return TYPE_ERROR;
-
-fault:
-	return TYPE_FAULT;
-}
-
-static int
-do_alignment_ldrstr(unsigned long addr, unsigned long instr, struct pt_regs *regs)
-{
-	unsigned int rd = RD_BITS(instr);
-
-	ai_word += 1;
-
-	if (!LDST_P_BIT(instr) && LDST_W_BIT(instr))
-		goto trans;
-
-	if (LDST_L_BIT(instr))
-		get32_unaligned_check(regs->uregs[rd], addr);
-	else
-		put32_unaligned_check(regs->uregs[rd], addr);
-	return TYPE_LDST;
-
-trans:
-	if (LDST_L_BIT(instr))
-		get32t_unaligned_check(regs->uregs[rd], addr);
-	else
-		put32t_unaligned_check(regs->uregs[rd], addr);
-	return TYPE_LDST;
-
-fault:
-	return TYPE_FAULT;
-}
-
-/*
- * LDM/STM alignment handler.
- *
- * There are 4 variants of this instruction:
- *
- * B = rn pointer before instruction, A = rn pointer after instruction
- *              ------ increasing address ----->
- *	        |    | r0 | r1 | ... | rx |    |
- * PU = 01             B                    A
- * PU = 11        B                    A
- * PU = 00        A                    B
- * PU = 10             A                    B
- */
-static int
-do_alignment_ldmstm(unsigned long addr, unsigned long instr, struct pt_regs *regs)
-{
-	unsigned int rd, rn, correction, nr_regs, regbits;
-	unsigned long eaddr, newaddr;
-
-	if (LDM_S_BIT(instr))
-		goto bad;
-
-	correction = 4; /* processor implementation defined */
-	regs->ARM_pc += correction;
-
-	ai_multi += 1;
-
-	/* count the number of registers in the mask to be transferred */
-	nr_regs = hweight16(REGMASK_BITS(instr)) * 4;
-
-	rn = RN_BITS(instr);
-	newaddr = eaddr = regs->uregs[rn];
-
-	if (!LDST_U_BIT(instr))
-		nr_regs = -nr_regs;
-	newaddr += nr_regs;
-	if (!LDST_U_BIT(instr))
-		eaddr = newaddr;
-
-	if (LDST_P_EQ_U(instr))	/* U = P */
-		eaddr += 4;
-
-	/*
-	 * This is a "hint" - we already have eaddr worked out by the
-	 * processor for us.
-	 */
-	if (addr != eaddr) {
-		printk(KERN_ERR "LDMSTM: PC = %08lx, instr = %08lx, "
-			"addr = %08lx, eaddr = %08lx\n",
-			 instruction_pointer(regs), instr, addr, eaddr);
-		show_regs(regs);
-	}
-
-	for (regbits = REGMASK_BITS(instr), rd = 0; regbits; regbits >>= 1, rd += 1)
-		if (regbits & 1) {
-			if (LDST_L_BIT(instr))
-				get32_unaligned_check(regs->uregs[rd], eaddr);
-			else
-				put32_unaligned_check(regs->uregs[rd], eaddr);
-			eaddr += 4;
-		}
-
-	if (LDST_W_BIT(instr))
-		regs->uregs[rn] = newaddr;
-	if (!LDST_L_BIT(instr) || !(REGMASK_BITS(instr) & (1 << 15)))
-		regs->ARM_pc -= correction;
-	return TYPE_DONE;
-
-fault:
-	regs->ARM_pc -= correction;
-	return TYPE_FAULT;
-
-bad:
-	printk(KERN_ERR "Alignment trap: not handling ldm with s-bit set\n");
-	return TYPE_ERROR;
-}
-
-static int
-do_alignment(unsigned long addr, int error_code, struct pt_regs *regs)
-{
-	union offset_union offset;
-	unsigned long instr, instrptr;
-	int (*handler)(unsigned long addr, unsigned long instr, struct pt_regs *regs);
-	unsigned int type;
-
-	if (user_mode(regs))
-		goto user;
-
-	ai_sys += 1;
-
-	instrptr = instruction_pointer(regs);
-	instr = *(unsigned long *)instrptr;
-
-	regs->ARM_pc += 4;
-
-	switch (CODING_BITS(instr)) {
-	case 0x00000000:	/* ldrh or strh */
-		if (LDSTH_I_BIT(instr))
-			offset.un = (instr & 0xf00) >> 4 | (instr & 15);
-		else
-			offset.un = regs->uregs[RM_BITS(instr)];
-		handler = do_alignment_ldrhstrh;
-		break;
-
-	case 0x04000000:	/* ldr or str immediate */
-		offset.un = OFFSET_BITS(instr);
-		handler = do_alignment_ldrstr;
-		break;
-
-	case 0x06000000:	/* ldr or str register */
-		offset.un = regs->uregs[RM_BITS(instr)];
-
-		if (IS_SHIFT(instr)) {
-			unsigned int shiftval = SHIFT_BITS(instr);
-
-			switch(SHIFT_TYPE(instr)) {
-			case SHIFT_LSL:
-				offset.un <<= shiftval;
-				break;
-
-			case SHIFT_LSR:
-				offset.un >>= shiftval;
-				break;
-
-			case SHIFT_ASR:
-				offset.sn >>= shiftval;
-				break;
-
-			case SHIFT_RORRRX:
-				if (shiftval == 0) {
-					offset.un >>= 1;
-					if (regs->ARM_cpsr & CC_C_BIT)
-						offset.un |= 1 << 31;
-				} else
-					offset.un = offset.un >> shiftval |
-							  offset.un << (32 - shiftval);
-				break;
-			}
-		}
-		handler = do_alignment_ldrstr;
-		break;
-
-	case 0x08000000:	/* ldm or stm */
-		handler = do_alignment_ldmstm;
-		break;
-
-	default:
-		goto bad;
-	}
-
-	type = handler(addr, instr, regs);
-
-	if (type == TYPE_ERROR || type == TYPE_FAULT)
-		goto bad_or_fault;
-
-	if (type == TYPE_LDST)
-		do_alignment_finish_ldst(addr, instr, regs, offset);
-
-	return 0;
-
-bad_or_fault:
-	if (type == TYPE_ERROR)
-		goto bad;
-	regs->ARM_pc -= 4;
-	/*
-	 * We got a fault - fix it up, or die.
-	 */
-	do_bad_area(current, current->mm, addr, error_code, regs);
-	return 0;
-
-bad:
-	/*
-	 * Oops, we didn't handle the instruction.
-	 */
-	printk(KERN_ERR "Alignment trap: not handling instruction "
-		"%08lx at [<%08lx>]\n", instr, instrptr);
-	ai_skipped += 1;
-	return 1;
-
-user:
-	set_cr(cr_no_alignment);
-	ai_user += 1;
-	return 0;
-}
-
+extern int do_alignment(unsigned long addr, int error_code, struct pt_regs *regs);
 #else
-
-#define do_alignment NULL
-
+#define do_alignment do_bad
 #endif
 
+
 /*
- * Some section permission faults need to be handled gracefully, for
- * instance, when they happen due to a __{get,put}_user during an oops).
+ * Some section permission faults need to be handled gracefully.
+ * They can happen due to a __{get,put}_user during an oops.
  */
 static int
 do_sect_fault(unsigned long addr, int error_code, struct pt_regs *regs)
@@ -557,73 +72,54 @@
 	return 1;
 }
 
+/*
+ * This abort handler always returns "fault".
+ */
+static int
+do_bad(unsigned long addr, int error_code, struct pt_regs *regs)
+{
+	return 1;
+}
+
 static const struct fsr_info {
 	int	(*fn)(unsigned long addr, int error_code, struct pt_regs *regs);
 	int	sig;
-	char	*name;
+	const char *name;
 } fsr_info[] = {
-	{ NULL,			SIGSEGV, "vector exception"		   },
+	{ do_bad,		SIGSEGV, "vector exception"		   },
 	{ do_alignment,		SIGILL,	 "alignment exception"		   },
-	{ NULL,			SIGKILL, "terminal exception"		   },
+	{ do_bad,		SIGKILL, "terminal exception"		   },
 	{ do_alignment,		SIGILL,	 "alignment exception"		   },
 	{ do_external_fault,	SIGBUS,	 "external abort on linefetch"	   },
 	{ do_translation_fault,	SIGSEGV, "section translation fault"	   },
 	{ do_external_fault,	SIGBUS,	 "external abort on linefetch"	   },
 	{ do_page_fault,	SIGSEGV, "page translation fault"	   },
 	{ do_external_fault,	SIGBUS,	 "external abort on non-linefetch" },
-	{ NULL,			SIGSEGV, "section domain fault"		   },
+	{ do_bad,		SIGSEGV, "section domain fault"		   },
 	{ do_external_fault,	SIGBUS,	 "external abort on non-linefetch" },
-	{ NULL,			SIGSEGV, "page domain fault"		   },
-	{ NULL,			SIGBUS,	 "external abort on translation"   },
+	{ do_bad,		SIGSEGV, "page domain fault"		   },
+	{ do_bad,		SIGBUS,	 "external abort on translation"   },
 	{ do_sect_fault,	SIGSEGV, "section permission fault"	   },
-	{ NULL,			SIGBUS,	 "external abort on translation"   },
+	{ do_bad,		SIGBUS,	 "external abort on translation"   },
 	{ do_page_fault,	SIGSEGV, "page permission fault"	   }
 };
 
 /*
- * Currently dropped down to debug level
+ * Dispatch a data abort to the relevant handler.
  */
 asmlinkage void
 do_DataAbort(unsigned long addr, int error_code, struct pt_regs *regs, int fsr)
 {
 	const struct fsr_info *inf = fsr_info + (fsr & 15);
 
-#if defined(CONFIG_CPU_SA110) || defined(CONFIG_CPU_SA1100) || defined(CONFIG_DEBUG_ERRORS)
-	if (addr == regs->ARM_pc)
-		goto sa1_weirdness;
-#endif
-
-	if (!inf->fn)
-		goto bad;
-
 	if (!inf->fn(addr, error_code, regs))
 		return;
-bad:
-	printk(KERN_ALERT "Unhandled fault: %s (%X) at 0x%08lx\n",
+
+	printk(KERN_ALERT "Unhandled fault: %s (0x%03x) at 0x%08lx\n",
 		inf->name, fsr, addr);
-	show_pte(current->mm, addr);
 	force_sig(inf->sig, current);
+	show_pte(current->mm, addr);
 	die_if_kernel("Oops", regs, 0);
-	return;
-
-#if defined(CONFIG_CPU_SA110) || defined(CONFIG_CPU_SA1100) || defined(CONFIG_DEBUG_ERRORS)
-sa1_weirdness:
-	if (user_mode(regs)) {
-		static int first = 1;
-		if (first) {
-			printk(KERN_DEBUG "Fixing up bad data abort at %08lx\n", addr);
-#ifdef CONFIG_DEBUG_ERRORS
-			show_pte(current->mm, addr);
-#endif
-		}
-		first = 0;
-		return;
-	}
-
-	if (!inf->fn || inf->fn(addr, error_code, regs))
-		goto bad;
-	return;
-#endif
 }
 
 asmlinkage void
@@ -680,38 +176,13 @@
 	return;
 }
 
-/*
- * Take care of architecture specific things when placing a new PTE into
- * a page table, or changing an existing PTE.  Basically, there are two
- * things that we need to take care of:
- *
- *  1. If PG_dcache_dirty is set for the page, we need to ensure
- *     that any cache entries for the kernels virtual memory
- *     range are written back to the page.
- *  2. If we have multiple shared mappings of the same space in
- *     an object, we need to deal with the cache aliasing issues.
- *
- * Note that the page_table_lock will be held.
- */
-void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
+static void
+make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page)
 {
-	struct page *page = pte_page(pte);
 	struct vm_area_struct *mpnt;
-	struct mm_struct *mm;
-	unsigned long pgoff;
-	int aliases;
-
-	if (!VALID_PAGE(page) || !page->mapping)
-		return;
-
-	if (test_and_clear_bit(PG_dcache_dirty, &page->flags)) {
-		unsigned long kvirt = (unsigned long)page_address(page);
-		cpu_cache_clean_invalidate_range(kvirt, kvirt + PAGE_SIZE, 0);
-	}
-
-	mm = vma->vm_mm;
-	pgoff = (addr - vma->vm_start) >> PAGE_SHIFT;
-	aliases = 0;
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long pgoff = (addr - vma->vm_start) >> PAGE_SHIFT;
+	int aliases = 0;
 
 	/*
 	 * If we have any shared mappings that are in the same mm
@@ -727,7 +198,7 @@
 		 * Note that we intentionally don't mask out the VMA
 		 * that we are fixing up.
 		 */
-		if (mpnt->vm_mm != mm && mpnt != vma)
+		if (mpnt->vm_mm != mm || mpnt == vma)
 			continue;
 
 		/*
@@ -748,4 +219,31 @@
 	}
 	if (aliases)
 		adjust_pte(vma, addr);
+}
+
+/*
+ * Take care of architecture specific things when placing a new PTE into
+ * a page table, or changing an existing PTE.  Basically, there are two
+ * things that we need to take care of:
+ *
+ *  1. If PG_dcache_dirty is set for the page, we need to ensure
+ *     that any cache entries for the kernels virtual memory
+ *     range are written back to the page.
+ *  2. If we have multiple shared mappings of the same space in
+ *     an object, we need to deal with the cache aliasing issues.
+ *
+ * Note that the page_table_lock will be held.
+ */
+void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
+{
+	struct page *page = pte_page(pte);
+
+	if (VALID_PAGE(page) && page->mapping) {
+		if (test_and_clear_bit(PG_dcache_dirty, &page->flags)) {
+			unsigned long kvirt = (unsigned long)page_address(page);
+			cpu_cache_clean_invalidate_range(kvirt, kvirt + PAGE_SIZE, 0);
+		}
+
+		make_coherent(vma, addr, page);
+	}
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mm/fault-common.c linux/arch/arm/mm/fault-common.c
--- linux.orig/arch/arm/mm/fault-common.c	Thu Oct 11 16:04:57 2001
+++ linux/arch/arm/mm/fault-common.c	Tue May 28 22:39:14 2002
@@ -141,6 +141,7 @@
 	printk(KERN_DEBUG "%s: unhandled page fault at pc=0x%08lx, "
 	       "lr=0x%08lx (bad address=0x%08lx, code %d)\n",
 	       tsk->comm, regs->ARM_pc, regs->ARM_lr, addr, error_code);
+	show_regs(regs);
 #endif
 
 	tsk->thread.address = addr;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mm/mm-armv.c linux/arch/arm/mm/mm-armv.c
--- linux.orig/arch/arm/mm/mm-armv.c	Wed Jun 27 21:12:04 2001
+++ linux/arch/arm/mm/mm-armv.c	Tue May 28 22:39:16 2002
@@ -14,10 +14,10 @@
 #include <linux/init.h>
 #include <linux/bootmem.h>
 
+#include <asm/hardware.h>
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
 #include <asm/page.h>
-#include <asm/io.h>
 #include <asm/setup.h>
 
 #include <asm/mach/map.h>
@@ -224,6 +224,19 @@
 	unsigned long virt, length;
 	int prot_sect, prot_pte;
 	long off;
+
+	if (md->prot_read && md->prot_write &&
+	    !md->cacheable && !md->bufferable) {
+		printk(KERN_WARNING "Security risk: creating user "
+		       "accessible mapping for 0x%08lx at 0x%08lx\n",
+		       md->physical, md->virtual);
+	}
+
+	if (md->virtual != vectors_base() && md->virtual < PAGE_OFFSET) {
+		printk(KERN_WARNING "MM: not creating mapping for "
+		       "0x%08lx at 0x%08lx in user region\n",
+		       md->physical, md->virtual);
+	}
 
 	prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
 		   (md->prot_read  ? L_PTE_USER       : 0) |
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mm/proc-arm1020.S linux/arch/arm/mm/proc-arm1020.S
--- linux.orig/arch/arm/mm/proc-arm1020.S	Fri Nov  9 21:58:02 2001
+++ linux/arch/arm/mm/proc-arm1020.S	Tue May 28 22:39:15 2002
@@ -56,22 +56,27 @@
  * cpu_arm1020_data_abort()
  *
  * obtain information about current aborted instruction
+ * Note: we read user space.  This means we might cause a data
+ * abort here if the I-TLB and D-TLB aren't seeing the same
+ * picture.  Unfortunately, this does happen.  We live with it.
  *
- * r0 = address of aborted instruction
+ *  r2 = address of aborted instruction
+ *  r3 = cpsr
  *
  * Returns:
  *  r0 = address of abort
  *  r1 != 0 if writing
  *  r3 = FSR
+ *  r4 = corrupted
  */
 	.align	5
 ENTRY(cpu_arm1020_data_abort)
-	ldr	r1, [r0]			@ read aborted instruction
+	mrc	p15, 0, r3, c5, c0, 0		@ get FSR
 	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
+	ldr	r1, [r2]			@ read aborted instruction
+	and	r3, r3, #255
 	tst	r1, r1, lsr #21 		@ C = bit 20
-	mrc	p15, 0, r3, c5, c0, 0		@ get FSR
 	sbc	r1, r1, r1			@ r1 = C - 1
-	and	r3, r3, #255
 	mov	pc, lr
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mm/proc-arm720.S linux/arch/arm/mm/proc-arm720.S
--- linux.orig/arch/arm/mm/proc-arm720.S	Thu Oct 11 16:04:57 2001
+++ linux/arch/arm/mm/proc-arm720.S	Tue May 28 22:39:16 2002
@@ -111,6 +111,9 @@
  *         : r3 = saved SPSR
  *
  * Purpose : obtain information about current aborted instruction
+ * Note: we read user space.  This means we might cause a data
+ * abort here if the I-TLB and D-TLB aren't seeing the same
+ * picture.  Unfortunately, this does happen.  We live with it.
  *
  * Returns : r0 = address of abort
  *	   : r1 != 0 if writing
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mm/proc-arm920.S linux/arch/arm/mm/proc-arm920.S
--- linux.orig/arch/arm/mm/proc-arm920.S	Thu Oct 25 20:53:46 2001
+++ linux/arch/arm/mm/proc-arm920.S	Tue May 28 22:39:14 2002
@@ -56,22 +56,27 @@
  * cpu_arm920_data_abort()
  *
  * obtain information about current aborted instruction
+ * Note: we read user space.  This means we might cause a data
+ * abort here if the I-TLB and D-TLB aren't seeing the same
+ * picture.  Unfortunately, this does happen.  We live with it.
  *
- * r0 = address of aborted instruction
+ *  r2 = address of aborted instruction
+ *  r3 = cpsr
  *
  * Returns:
  *  r0 = address of abort
  *  r1 != 0 if writing
  *  r3 = FSR
+ *  r4 = corrupted
  */
 	.align	5
 ENTRY(cpu_arm920_data_abort)
-	ldr	r1, [r0]			@ read aborted instruction
+	mrc	p15, 0, r3, c5, c0, 0		@ get FSR
 	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
+	ldr	r1, [r2]			@ read aborted instruction
+	and	r3, r3, #255
 	tst	r1, r1, lsr #21			@ C = bit 20
-	mrc	p15, 0, r3, c5, c0, 0		@ get FSR
 	sbc	r1, r1, r1			@ r1 = C - 1
-	and	r3, r3, #255
 	mov	pc, lr
 	
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mm/proc-arm922.S linux/arch/arm/mm/proc-arm922.S
--- linux.orig/arch/arm/mm/proc-arm922.S	Thu Jan  1 00:00:00 1970
+++ linux/arch/arm/mm/proc-arm922.S	Tue May 28 22:39:27 2002
@@ -0,0 +1,657 @@
+/*
+ *  linux/arch/arm/mm/arm922.S: MMU functions for ARM922
+ *
+ *  Copyright (C) 1999,2000 ARM Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd.
+ *  Copyright (C) 2001 Altera Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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
+ *
+ *
+ * These are the low level assembler for performing cache and TLB
+ * functions on the arm922.
+ */
+#include <linux/linkage.h>
+#include <linux/config.h>
+#include <asm/assembler.h>
+#include <asm/constants.h>
+#include <asm/procinfo.h>
+#include <asm/hardware.h>
+
+/*
+ * This is the maximum size of an area which will be invalidated
+ * using the single invalidate entry instructions.  Anything larger
+ * than this, and we go for the whole cache.
+ *
+ * This value should be chosen such that we choose the cheapest
+ * alternative.
+ */
+#define MAX_AREA_SIZE	8192
+
+/*
+ * the cache line size of the I and D cache
+ */
+#define DCACHELINESIZE	32
+#define ICACHELINESIZE	32
+
+/*
+ * and the page size
+ */
+#define PAGESIZE	4096
+
+	.text
+
+/*
+ * cpu_arm922_data_abort()
+ *
+ * obtain information about current aborted instruction
+ *
+ * r0 = address of aborted instruction
+ *
+ * Returns:
+ *  r0 = address of abort
+ *  r1 != 0 if writing
+ *  r3 = FSR
+ */
+	.align	5
+ENTRY(cpu_arm922_data_abort)
+	ldr	r1, [r0]			@ read aborted instruction
+	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
+	tst	r1, r1, lsr #21			@ C = bit 20
+	mrc	p15, 0, r3, c5, c0, 0		@ get FSR
+	sbc	r1, r1, r1			@ r1 = C - 1
+	and	r3, r3, #255
+	mov	pc, lr
+	
+/*
+ * cpu_arm922_check_bugs()
+ */
+ENTRY(cpu_arm922_check_bugs)
+	mrs	ip, cpsr
+	bic	ip, ip, #F_BIT
+	msr	cpsr, ip
+	mov	pc, lr
+
+/*
+ * cpu_arm922_proc_init()
+ */
+ENTRY(cpu_arm922_proc_init)
+	mov	pc, lr
+
+/*
+ * cpu_arm922_proc_fin()
+ */
+ENTRY(cpu_arm922_proc_fin)
+	stmfd	sp!, {lr}
+	mov	ip, #F_BIT | I_BIT | SVC_MODE
+	msr	cpsr_c, ip
+	bl	cpu_arm922_cache_clean_invalidate_all
+	mrc	p15, 0, r0, c1, c0, 0		@ ctrl register
+	bic	r0, r0, #0x1000			@ ...i............
+	bic	r0, r0, #0x000e			@ ............wca.
+	mcr	p15, 0, r0, c1, c0, 0		@ disable caches
+	ldmfd	sp!, {pc}
+
+/*
+ * cpu_arm922_reset(loc)
+ *
+ * Perform a soft reset of the system.  Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * loc: location to jump to for soft reset
+ */
+	.align	5
+ENTRY(cpu_arm922_reset)
+	mov	ip, #0
+	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches
+	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
+	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
+	mrc	p15, 0, ip, c1, c0, 0		@ ctrl register
+	bic	ip, ip, #0x000f			@ ............wcam
+	bic	ip, ip, #0x1100			@ ...i...s........
+	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
+	mov	pc, r0
+
+/*
+ * cpu_arm922_do_idle()
+ */
+	.align	5
+ENTRY(cpu_arm922_do_idle)
+#if defined(CONFIG_CPU_ARM922_CPU_IDLE)
+	mcr	p15, 0, r0, c7, c0, 4		@ Wait for interrupt
+#endif
+	mov	pc, lr
+
+/* ================================= CACHE ================================ */
+
+
+/*
+ * cpu_arm922_cache_clean_invalidate_all()
+ *
+ * clean and invalidate all cache lines
+ *
+ * Note:
+ *  1. we should preserve r0 at all times
+ */
+	.align	5
+ENTRY(cpu_arm922_cache_clean_invalidate_all)
+	mov	r2, #1
+cpu_arm922_cache_clean_invalidate_all_r2:
+	mov	ip, #0
+#ifdef CONFIG_CPU_ARM922_WRITETHROUGH
+	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
+#else
+/*
+ * 'Clean & Invalidate whole DCache'
+ * Re-written to use Index Ops.
+ * Uses registers r1, r3 and ip
+ */
+	mov	r1, #3 << 5			@ 4 segments
+1:	orr	r3, r1, #63 << 26		@ 64 entries
+2:	mcr	p15, 0, r3, c7, c14, 2		@ clean & invalidate D index
+	subs	r3, r3, #1 << 26
+	bcs	2b				@ entries 63 to 0
+	subs	r1, r1, #1 << 5
+	bcs	1b				@ segments 7 to 0
+#endif
+	teq	r2, #0
+	mcrne	p15, 0, ip, c7, c5, 0		@ invalidate I cache
+	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ * cpu_arm922_cache_clean_invalidate_range(start, end, flags)
+ *
+ * clean and invalidate all cache lines associated with this area of memory
+ *
+ * start: Area start address
+ * end:   Area end address
+ * flags: nonzero for I cache as well
+ */
+		.align	5
+ENTRY(cpu_arm922_cache_clean_invalidate_range)
+	bic	r0, r0, #DCACHELINESIZE - 1	@ && added by PGM
+	bic	r1, r1, #DCACHELINESIZE - 1     @ && added by DHM
+	sub	r3, r1, r0
+	cmp	r3, #MAX_AREA_SIZE
+	bgt	cpu_arm922_cache_clean_invalidate_all_r2
+1:	teq	r2, #0
+#ifdef CONFIG_CPU_ARM922_WRITETHROUGH
+	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
+	add	r0, r0, #DCACHELINESIZE
+#else
+	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
+	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
+	mcrne	p15, 0, r0, c7, c5, 1		@ invalidate I entry
+	add	r0, r0, #DCACHELINESIZE
+#endif
+	cmp	r0, r1
+	blt	1b
+
+	mcr	p15, 0, r1, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ * cpu_arm922_flush_ram_page(page)
+ *
+ * clean and invalidate all cache lines associated with this area of memory
+ *
+ * page: page to clean and invalidate
+ */
+	.align	5
+ENTRY(cpu_arm922_flush_ram_page)
+	mov	r1, #PAGESIZE
+#ifdef CONFIG_CPU_ARM922_WRITETHROUGH
+1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+#else
+1:	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c14, 1		@ clean and invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+#endif
+	subs	r1, r1, #2 * DCACHELINESIZE
+	bne	1b
+	mcr	p15, 0, r1, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/* ================================ D-CACHE =============================== */
+
+/*
+ * cpu_arm922_dcache_invalidate_range(start, end)
+ *
+ * throw away all D-cached data in specified region without an obligation
+ * to write them back.  Note however that we must clean the D-cached entries
+ * around the boundaries if the start and/or end address are not cache
+ * aligned.
+ *
+ * start: virtual start address
+ * end:   virtual end address
+ */
+	.align	5
+ENTRY(cpu_arm922_dcache_invalidate_range)
+#ifndef CONFIG_CPU_ARM922_WRITETHROUGH
+	tst	r0, #DCACHELINESIZE - 1
+	mcrne	p15, 0, r0, c7, c10, 1		@ clean D entry
+	tst	r1, #DCACHELINESIZE - 1
+	mcrne	p15, 0, r1, c7, c10, 1		@ clean D entry
+#endif		@ clean D entry
+	bic	r0, r0, #DCACHELINESIZE - 1
+	bic	r1, r1, #DCACHELINESIZE - 1
+1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
+	add	r0, r0, #DCACHELINESIZE
+	cmp	r0, r1
+	blt	1b
+	mov	pc, lr
+
+/*
+ * cpu_arm922_dcache_clean_range(start, end)
+ *
+ * For the specified virtual address range, ensure that all caches contain
+ * clean data, such that peripheral accesses to the physical RAM fetch
+ * correct data.
+ *
+ * start: virtual start address
+ * end:   virtual end address
+ */
+	.align	5
+ENTRY(cpu_arm922_dcache_clean_range)
+#ifndef CONFIG_CPU_ARM922_WRITETHROUGH
+	bic	r0, r0, #DCACHELINESIZE - 1
+	sub	r1, r1, r0
+	cmp	r1, #MAX_AREA_SIZE
+	mov	r2, #0
+	bgt	cpu_arm922_cache_clean_invalidate_all_r2
+
+	bic	r1, r1, #DCACHELINESIZE -1
+	add	r1, r1, #DCACHELINESIZE
+
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #DCACHELINESIZE
+	subs	r1, r1, #DCACHELINESIZE
+	bpl	1b
+#endif
+	mcr	p15, 0, r2, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ * cpu_arm922_dcache_clean_page(page)
+ *
+ * Cleans a single page of dcache so that if we have any future aliased
+ * mappings, they will be consistent at the time that they are created.
+ *
+ * page: virtual address of page to clean from dcache
+ *
+ * Note:
+ *  1. we don't need to flush the write buffer in this case.
+ *  2. we don't invalidate the entries since when we write the page
+ *     out to disk, the entries may get reloaded into the cache.
+ */
+	.align	5
+ENTRY(cpu_arm922_dcache_clean_page)
+#ifndef CONFIG_CPU_ARM922_WRITETHROUGH
+	mov	r1, #PAGESIZE
+1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #DCACHELINESIZE
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	add	r0, r0, #DCACHELINESIZE
+	subs	r1, r1, #2 * DCACHELINESIZE
+	bne	1b
+#endif
+	mov	pc, lr
+
+/*
+ * cpu_arm922_dcache_clean_entry(addr)
+ *
+ * Clean the specified entry of any caches such that the MMU
+ * translation fetches will obtain correct data.
+ *
+ * addr: cache-unaligned virtual address
+ */
+	.align	5
+ENTRY(cpu_arm922_dcache_clean_entry)
+#ifndef CONFIG_CPU_ARM922_WRITETHROUGH
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+#endif
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/* ================================ I-CACHE =============================== */
+
+/*
+ * cpu_arm922_icache_invalidate_range(start, end)
+ *
+ * invalidate a range of virtual addresses from the Icache
+ *
+ * This is a little misleading, it is not intended to clean out
+ * the i-cache but to make sure that any data written to the
+ * range is made consistant.  This means that when we execute code
+ * in that region, everything works as we expect.
+ *
+ * This generally means writing back data in the Dcache and
+ * write buffer and flushing the Icache over that region
+ *
+ * start: virtual start address
+ * end:   virtual end address
+ *
+ * NOTE: ICACHELINESIZE == DCACHELINESIZE (so we don't need to
+ * loop twice, once for i-cache, once for d-cache)
+ */
+	.align	5
+ENTRY(cpu_arm922_icache_invalidate_range)
+	bic	r0, r0, #ICACHELINESIZE - 1	@ Safety check
+	sub	r1, r1, r0
+	cmp	r1, #MAX_AREA_SIZE
+	bgt	cpu_arm922_cache_clean_invalidate_all_r2
+
+	bic	r1, r1, #ICACHELINESIZE - 1
+	add	r1, r1, #ICACHELINESIZE
+
+1:	mcr	p15, 0, r0, c7, c5, 1		@ Clean I entry
+	mcr	p15, 0, r0, c7, c10, 1		@ Clean D entry
+	add	r0, r0, #ICACHELINESIZE
+	subs	r1, r1, #ICACHELINESIZE
+	bne	1b
+
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+ENTRY(cpu_arm922_icache_invalidate_page)
+	mcr	p15, 0, r0, c7, c5, 0		@ invalidate I cache
+	mov	pc, lr
+
+/* ================================== TLB ================================= */
+
+/*
+ * cpu_arm922_tlb_invalidate_all()
+ *
+ * Invalidate all TLB entries
+ */
+	.align	5
+ENTRY(cpu_arm922_tlb_invalidate_all)
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mcr	p15, 0, r0, c8, c7, 0		@ invalidate I & D TLBs
+	mov	pc, lr
+
+/*
+ * cpu_arm922_tlb_invalidate_range(start, end)
+ *
+ * invalidate TLB entries covering the specified range
+ *
+ * start: range start address
+ * end:   range end address
+ */
+	.align	5
+ENTRY(cpu_arm922_tlb_invalidate_range)
+	mov	r3, #0
+	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
+
+	mov	r3, #PAGESIZE
+	sub	r3, r3, #1
+	bic 	r0, r0, r3
+	bic	r1, r1, r3
+
+1:	mcr	p15, 0, r0, c8, c6, 1		@ invalidate D TLB entry
+	mcr	p15, 0, r0, c8, c5, 1		@ invalidate I TLB entry
+	add	r0, r0, #PAGESIZE
+	cmp	r0, r1
+	blt	1b
+	mov	pc, lr
+
+/*
+ * cpu_arm922_tlb_invalidate_page(page, flags)
+ *
+ * invalidate the TLB entries for the specified page.
+ *
+ * page:  page to invalidate
+ * flags: non-zero if we include the I TLB
+ */
+	.align	5
+ENTRY(cpu_arm922_tlb_invalidate_page)
+	mov	r3, #0
+	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
+	teq	r1, #0
+	mcr	p15, 0, r0, c8, c6, 1		@ invalidate D TLB entry
+	mcrne	p15, 0, r0, c8, c5, 1		@ invalidate I TLB entry
+	mov	pc, lr
+
+/* =============================== PageTable ============================== */
+
+/*
+ * cpu_arm922_set_pgd(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+	.align	5
+ENTRY(cpu_arm922_set_pgd)
+	mov	ip, #0
+#ifdef CONFIG_CPU_ARM922_WRITETHROUGH
+	/* Any reason why we don't use mcr p15, 0, r0, c7, c7, 0 here? --rmk */
+	mcr	p15, 0, ip, c7, c6, 0		@ invalidate D cache
+#else
+@ && 'Clean & Invalidate whole DCache'
+@ && Re-written to use Index Ops.
+@ && Uses registers r1, r3 and ip
+
+	mov	r1, #3 << 5			@ 4 segments
+1:	orr	r3, r1, #63 << 26		@ 64 entries
+2:	mcr	p15, 0, r3, c7, c14, 2		@ clean & invalidate D index
+	subs	r3, r3, #1 << 26
+	bcs	2b				@ entries 63 to 0
+	subs	r1, r1, #1 << 5
+	bcs	1b				@ segments 7 to 0
+#endif
+	mcr	p15, 0, ip, c7, c5, 0		@ invalidate I cache
+	mcr	p15, 0, ip, c7, c10, 4		@ drain WB
+	mcr	p15, 0, r0, c2, c0, 0		@ load page table pointer
+	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
+	mov	pc, lr
+
+/*
+ * cpu_arm922_set_pmd(pmdp, pmd)
+ *
+ * Set a level 1 translation table entry, and clean it out of
+ * any caches such that the MMUs can load it correctly.
+ *
+ * pmdp: pointer to PMD entry
+ * pmd:  PMD value to store
+ */
+	.align	5
+ENTRY(cpu_arm922_set_pmd)
+#ifdef CONFIG_CPU_ARM922_WRITETHROUGH
+	eor	r2, r1, #0x0a			@ C & Section
+	tst	r2, #0x0b
+	biceq	r1, r1, #4			@ clear bufferable bit
+#endif
+	str	r1, [r0]
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+/*
+ * cpu_arm922_set_pte(ptep, pte)
+ *
+ * Set a PTE and flush it out
+ */
+	.align	5
+ENTRY(cpu_arm922_set_pte)
+	str	r1, [r0], #-1024		@ linux version
+
+	eor	r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
+
+	bic	r2, r1, #0xff0
+	bic	r2, r2, #3
+	orr	r2, r2, #HPTE_TYPE_SMALL
+
+	tst	r1, #LPTE_USER | LPTE_EXEC	@ User or Exec?
+	orrne	r2, r2, #HPTE_AP_READ
+
+	tst	r1, #LPTE_WRITE | LPTE_DIRTY	@ Write and Dirty?
+	orreq	r2, r2, #HPTE_AP_WRITE
+
+	tst	r1, #LPTE_PRESENT | LPTE_YOUNG	@ Present and Young?
+	movne	r2, #0
+
+#ifdef CONFIG_CPU_ARM922_WRITETHROUGH
+	eor	r3, r2, #0x0a			@ C & small page?
+	tst	r3, #0x0b
+	biceq	r2, r2, #4
+#endif
+	str	r2, [r0]			@ hardware version
+	mov	r0, r0
+	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
+
+cpu_manu_name:
+	.asciz	"ARM/ALTERA"
+ENTRY(cpu_arm922_name)
+	.ascii	"Arm922T"
+#if defined(CONFIG_CPU_ARM922_CPU_IDLE)
+	.ascii	"s"
+#endif
+#if defined(CONFIG_CPU_ARM922_I_CACHE_ON)
+	.ascii	"i"
+#endif
+#if defined(CONFIG_CPU_ARM922_D_CACHE_ON)
+	.ascii	"d"
+#if defined(CONFIG_CPU_ARM922_WRITETHROUGH)
+	.ascii	"(wt)"
+#else
+	.ascii	"(wb)"
+#endif
+#endif
+	.ascii	"\0"
+	.align
+
+	.section ".text.init", #alloc, #execinstr
+
+__arm922_setup:
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c7		@ invalidate I,D caches on v4
+	mcr	p15, 0, r0, c7, c10, 4		@ drain write buffer on v4
+	mcr	p15, 0, r0, c8, c7		@ invalidate I,D TLBs on v4
+	mcr	p15, 0, r4, c2, c0		@ load page table pointer
+	mov	r0, #0x1f			@ Domains 0, 1 = client
+	mcr	p15, 0, r0, c3, c0		@ load domain access register
+	mrc	p15, 0, r0, c1, c0		@ get control register v4
+/*
+ * Clear out 'unwanted' bits (then put them in if we need them)
+ */
+						@   VI ZFRS BLDP WCAM
+	bic	r0, r0, #0x0e00
+	bic	r0, r0, #0x0002
+	bic	r0, r0, #0x000c
+	bic	r0, r0, #0x1000			@ ...0 000. .... 000.
+/*
+ * Turn on what we want
+ */
+	orr	r0, r0, #0x0031
+	orr	r0, r0, #0x2100			@ ..1. ...1 ..11 ...1
+
+#ifdef CONFIG_CPU_ARM922_D_CACHE_ON
+	orr	r0, r0, #0x0004			@ .... .... .... .1..
+#endif
+#ifdef CONFIG_CPU_ARM922_I_CACHE_ON
+	orr	r0, r0, #0x1000			@ ...1 .... .... ....
+#endif
+	mov	pc, lr
+
+	.text
+
+/*
+ * Purpose : Function pointers used to access above functions - all calls
+ *	     come through these
+ */
+	.type	arm922_processor_functions, #object
+arm922_processor_functions:
+	.word	cpu_arm922_data_abort
+	.word	cpu_arm922_check_bugs
+	.word	cpu_arm922_proc_init
+	.word	cpu_arm922_proc_fin
+	.word	cpu_arm922_reset
+	.word   cpu_arm922_do_idle
+
+	/* cache */
+	.word	cpu_arm922_cache_clean_invalidate_all
+	.word	cpu_arm922_cache_clean_invalidate_range
+	.word	cpu_arm922_flush_ram_page
+
+	/* dcache */
+	.word	cpu_arm922_dcache_invalidate_range
+	.word	cpu_arm922_dcache_clean_range
+	.word	cpu_arm922_dcache_clean_page
+	.word	cpu_arm922_dcache_clean_entry
+
+	/* icache */
+	.word	cpu_arm922_icache_invalidate_range
+	.word	cpu_arm922_icache_invalidate_page
+
+	/* tlb */
+	.word	cpu_arm922_tlb_invalidate_all
+	.word	cpu_arm922_tlb_invalidate_range
+	.word	cpu_arm922_tlb_invalidate_page
+
+	/* pgtable */
+	.word	cpu_arm922_set_pgd
+	.word	cpu_arm922_set_pmd
+	.word	cpu_arm922_set_pte
+	.size	arm922_processor_functions, . - arm922_processor_functions
+
+	.type	cpu_arm922_info, #object
+cpu_arm922_info:
+	.long	cpu_manu_name
+	.long	cpu_arm922_name
+	.size	cpu_arm922_info, . - cpu_arm922_info
+
+	.type	cpu_arch_name, #object
+cpu_arch_name:
+	.asciz	"armv4"
+	.size	cpu_arch_name, . - cpu_arch_name
+
+	.type	cpu_elf_name, #object
+cpu_elf_name:
+	.asciz	"v4"
+	.size	cpu_elf_name, . - cpu_elf_name
+	.align
+
+	.section ".proc.info", #alloc, #execinstr
+
+	.type	__arm922_proc_info,#object
+__arm922_proc_info:
+	.long	0x41009220
+	.long	0xff00fff0
+	.long	0x00000c1e			@ mmuflags
+	b	__arm922_setup
+	.long	cpu_arch_name
+	.long	cpu_elf_name
+	.long	HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT
+	.long	cpu_arm922_info
+	.long	arm922_processor_functions
+	.size	__arm922_proc_info, . - __arm922_proc_info
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mm/proc-arm926.S linux/arch/arm/mm/proc-arm926.S
--- linux.orig/arch/arm/mm/proc-arm926.S	Fri Nov  9 21:58:02 2001
+++ linux/arch/arm/mm/proc-arm926.S	Tue May 28 22:39:12 2002
@@ -56,35 +56,39 @@
  * cpu_arm926_data_abort()
  *
  * obtain information about current aborted instruction
+ * Note: we read user space.  This means we might cause a data
+ * abort here if the I-TLB and D-TLB aren't seeing the same
+ * picture.  Unfortunately, this does happen.  We live with it.
  *
  * Inputs:
- *  r0 = address of abort 
- *  r1 = cpsr of abort 
+ *  r2 = address of abort 
+ *  r3 = cpsr of abort
  *
  * Returns:
  *  r0 = address of abort
  *  r1 != 0 if writing
  *  r3 = FSR
+ *  r4 = corrupted
  */
 	.align	5
 ENTRY(cpu_arm926_data_abort)
-	tst	r1, #1<<24			@ Check for Jbit (NE -> found)
-	movne	r1, #-1 			@ Mark as writing
+	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
+	mrc	p15, 0, r4, c5, c0, 0		@ get FSR
+
+	tst	r3, #1<<24			@ Check for Jbit (NE -> found)
+	movne	r3, #-1 			@ Mark as writing
 	bne	2f
 
-	tst	r1, #1<<5			@ Check for Thumb-bit (NE -> found)
-	ldrneh	r1, [r0]			@ Read aborted Thumb instruction        
+	tst	r3, #1<<5			@ Check for Thumb-bit (NE -> found)
+	ldrneh	r1, [r2]			@ Read aborted Thumb instruction        
 	tstne	r1, r1, lsr #12 		@ C = bit 11
 
-	ldreq	r1, [r0]			@ Read aborted ARM instruction
+	ldreq	r1, [r2]			@ Read aborted ARM instruction
 	tsteq	r1, r1, lsr #21 		@ C = bit 20
 
 	sbc	r1, r1, r1			@ r1 = C - 1
 2:
-	mrc	p15, 0, r3, c5, c0, 0		@ get FSR
-	and	r3, r3, #255
-	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
-
+	and	r3, r4, #255
 	mov	pc, lr
 
 /*
@@ -193,10 +197,9 @@
 	.align	5
 ENTRY(cpu_arm926_cache_clean_invalidate_range)
 	bic	r0, r0, #DCACHELINESIZE - 1	@ && added by PGM
-	bic	r1, r1, #DCACHELINESIZE - 1	@ && added by DHM
 	sub	r3, r1, r0
 	cmp	r3, #MAX_AREA_SIZE
-	bgt	cpu_arm926_cache_clean_invalidate_all_r2
+	bhi	cpu_arm926_cache_clean_invalidate_all_r2
 
 1:	teq	r2, #0
 #ifdef CONFIG_CPU_ARM926_WRITETHROUGH
@@ -216,7 +219,7 @@
 #endif
         
 	cmp	r0, r1
-	blt	1b
+	blo	1b
 
 	mcr	p15, 0, r1, c7, c10, 4		@ drain WB
 
@@ -267,14 +270,13 @@
 	tst	r0, #DCACHELINESIZE - 1
 	mcrne	p15, 0, r0, c7, c10, 1		@ clean D entry
 	tst	r1, #DCACHELINESIZE - 1
-	mcrne	p15, 0, r1, c7, c10, 1
-#endif		@ clean D entry
+	mcrne	p15, 0, r1, c7, c10, 1		@ clean D entry
+#endif
 	bic	r0, r0, #DCACHELINESIZE - 1
-	bic	r1, r1, #DCACHELINESIZE - 1
 1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
 	add	r0, r0, #DCACHELINESIZE
 	cmp	r0, r1
-	blt	1b
+	blo	1b
 	mov	pc, lr
 
 /*
@@ -291,18 +293,15 @@
 ENTRY(cpu_arm926_dcache_clean_range)
 #ifndef CONFIG_CPU_ARM926_WRITETHROUGH
 	bic	r0, r0, #DCACHELINESIZE - 1
-	sub	r1, r1, r0
-	cmp	r1, #MAX_AREA_SIZE
+	sub	r3, r1, r0
+	cmp	r3, #MAX_AREA_SIZE
 	mov	r2, #0
-	bgt	cpu_arm926_cache_clean_invalidate_all_r2
-
-	bic	r1, r1, #DCACHELINESIZE -1
-	add	r1, r1, #DCACHELINESIZE
+	bhi	cpu_arm926_cache_clean_invalidate_all_r2
 
 1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
 	add	r0, r0, #DCACHELINESIZE
-	subs	r1, r1, #DCACHELINESIZE
-	bpl	1b
+	cmp	r0, r1
+	blo	1b
 #endif
 	mcr	p15, 0, r2, c7, c10, 4		@ drain WB
 	mov	pc, lr
@@ -354,7 +353,12 @@
 /*
  * cpu_arm926_icache_invalidate_range(start, end)
  *
- * invalidate a range of virtual addresses from the Icache
+ * This *is not* just icache.  It is to make data written to memory
+ * consistent such that instructions fetched from the region are what
+ * we expect.
+ *
+ * This is typically used after we have copied a module into kernel space,
+ * and we're about to start executing code from that module.
  *
  * start: virtual start address
  * end:   virtual end address
@@ -362,17 +366,14 @@
 	.align	5
 ENTRY(cpu_arm926_icache_invalidate_range)
 	bic	r0, r0, #DCACHELINESIZE - 1	@ Safety check
-	sub	r1, r1, r0
-	cmp	r1, #MAX_AREA_SIZE
-	bgt	cpu_arm926_cache_clean_invalidate_all_r2
-
-	bic	r1, r1, #DCACHELINESIZE - 1
-	add	r1, r1, #DCACHELINESIZE
+	sub	r3, r1, r0
+	cmp	r3, #MAX_AREA_SIZE
+	bhi	cpu_arm926_cache_clean_invalidate_all_r2
 
 1:	mcr	p15, 0, r0, c7, c5, 1		@ clean I entries
 	add	r0, r0, #DCACHELINESIZE
-	subs	r1, r1, #DCACHELINESIZE
-	bne	1b
+	cmp	r0, r1
+	blo	1b
 
 	mov	r0, #0
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
@@ -410,16 +411,14 @@
 	mov	r3, #0
 	mcr	p15, 0, r3, c7, c10, 4		@ drain WB
 
-	mov	r3, #PAGESIZE
-	sub	r3, r3, #1
-	bic	r0, r0, r3
-	bic	r1, r1, r3
+	bic	r0, r0, #(PAGESIZE - 1) & 0x00ff
+	bic	r0, r0, #(PAGESIZE - 1) & 0xff00
 
 1:	mcr	p15, 0, r0, c8, c6, 1		@ invalidate D TLB entry
 	mcr	p15, 0, r0, c8, c5, 1		@ invalidate I TLB entry
 	add	r0, r0, #PAGESIZE
 	cmp	r0, r1
-	blt	1b
+	blo	1b
 	mov	pc, lr
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/mm/proc-sa110.S linux/arch/arm/mm/proc-sa110.S
--- linux.orig/arch/arm/mm/proc-sa110.S	Thu Oct 25 20:53:46 2001
+++ linux/arch/arm/mm/proc-sa110.S	Tue May 28 22:39:27 2002
@@ -69,24 +69,29 @@
 /*
  * cpu_sa110_data_abort()
  *
- * obtain information about current aborted instruction
+ * obtain information about current aborted instruction.
+ * Note: we read user space.  This means we might cause a data
+ * abort here if the I-TLB and D-TLB aren't seeing the same
+ * picture.  Unfortunately, this does happen.  We live with it.
  *
- * r0 = address of aborted instruction
+ *  r2 = address of aborted instruction
+ *  r3 = cpsr
  *
  * Returns:
  *  r0 = address of abort
  *  r1 != 0 if writing
  *  r3 = FSR
+ *  r4 = corrupted
  */
 	.align	5
 ENTRY(cpu_sa110_data_abort)
 ENTRY(cpu_sa1100_data_abort)
-	ldr	r1, [r0]			@ read aborted instruction
+	mrc	p15, 0, r3, c5, c0, 0		@ get FSR
 	mrc	p15, 0, r0, c6, c0, 0		@ get FAR
+	ldr	r1, [r2]			@ read aborted instruction
+	and	r3, r3, #255
 	tst	r1, r1, lsr #21			@ C = bit 20
-	mrc	p15, 0, r3, c5, c0, 0		@ get FSR
 	sbc	r1, r1, r1			@ r1 = C - 1
-	and	r3, r3, #255
 	mov	pc, lr
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/nwfpe/ARM-gcc.h linux/arch/arm/nwfpe/ARM-gcc.h
--- linux.orig/arch/arm/nwfpe/ARM-gcc.h	Thu Jun 17 08:11:35 1999
+++ linux/arch/arm/nwfpe/ARM-gcc.h	Tue May 28 22:39:25 2002
@@ -1,11 +1,3 @@
-
-/*
--------------------------------------------------------------------------------
-One of the macros `BIGENDIAN' or `LITTLEENDIAN' must be defined.
--------------------------------------------------------------------------------
-*/
-#define LITTLEENDIAN
-
 /*
 -------------------------------------------------------------------------------
 The macro `BITS64' can be defined to indicate that 64-bit integer types are
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/nwfpe/ChangeLog linux/arch/arm/nwfpe/ChangeLog
--- linux.orig/arch/arm/nwfpe/ChangeLog	Wed Oct 20 23:29:08 1999
+++ linux/arch/arm/nwfpe/ChangeLog	Tue May 28 22:39:28 2002
@@ -1,3 +1,26 @@
+2002-01-19  Russell King <rmk@arm.linux.org.uk>
+
+	* fpa11.h - Add documentation
+	          - remove userRegisters pointer from this structure.
+	          - add new method to obtain integer register values.
+	* softfloat.c - Remove float128
+	* softfloat.h - Remove float128
+	* softfloat-specialize - Remove float128
+
+	* The FPA11 structure is not a kernel-specific data structure.
+	  It is used by users of ptrace to examine the values of the
+	  floating point registers.  Therefore, any changes to the
+	  FPA11 structure (size or position of elements contained
+	  within) have to be well thought out.
+
+	* Since 128-bit float requires the FPA11 structure to change
+	  size, it has been removed.  128-bit float is currently unused,
+	  and needs various things to be re-worked so that we won't
+	  overflow the available space in the task structure.
+
+	* The changes are designed to break any patch that goes on top
+	  of this code, so that the authors properly review their changes.
+
 1999-08-19  Scott Bambrough  <scottb@netwinder.org>
 
 	* fpmodule.c - Changed version number to 0.95
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/nwfpe/double_cpdo.c linux/arch/arm/nwfpe/double_cpdo.c
--- linux.orig/arch/arm/nwfpe/double_cpdo.c	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/nwfpe/double_cpdo.c	Tue May 28 22:39:13 2002
@@ -19,9 +19,9 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
+#include "fpa11.h"
 #include "softfloat.h"
 #include "fpopcode.h"
-#include "fpa11.h"
 
 float64 float64_exp(float64 Fm);
 float64 float64_ln(float64 Fm);
@@ -165,8 +165,7 @@
 
       case RND_CODE:
       case URD_CODE:
-         fpa11->fpreg[Fd].fDouble = 
-             int32_to_float64(float64_to_int32(rFm));
+         fpa11->fpreg[Fd].fDouble = float64_round_to_int(rFm);
       break;
 
       case SQT_CODE:
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/nwfpe/entry.S linux/arch/arm/nwfpe/entry.S
--- linux.orig/arch/arm/nwfpe/entry.S	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/nwfpe/entry.S	Tue May 28 22:39:13 2002
@@ -50,11 +50,8 @@
 
 This routine does three things:
 
-1) It saves SP into a variable called userRegisters.  The kernel has
-created a struct pt_regs on the stack and saved the user registers
-into it.  See /usr/include/asm/proc/ptrace.h for details.  The
-emulator code uses userRegisters as the base of an array of words from
-which the contents of the registers can be extracted.
+1) The kernel has created a struct pt_regs on the stack and saved the
+user registers into it.  See inclue/asm-arm/proc/ptrace.h for details.
 
 2) It calls EmulateAll to emulate a floating point instruction.
 EmulateAll returns 1 if the emulation was successful, or 0 if not.
@@ -73,21 +70,16 @@
 
 	.globl	nwfpe_enter
 nwfpe_enter:
-	/* ?? Could put userRegisters and fpa11 into fixed regs during
-	   emulation.  This would reduce load/store overhead at the expense
-	   of stealing two regs from the register allocator.  Not sure if
-	   it's worth it.  */
-	str sp, [r10]                   @ Store the user registers pointer in the fpa11 structure.
-        mov r4, sp			@ use r4 for local pointer
-        mov r10, lr			@ save the failure-return addresses
+        mov r4, lr			@ save the failure-return addresses
+	mov sl, sp			@ we access the registers via 'sl'
 
-        ldr r5, [r4, #60]	 	@ get contents of PC;
+        ldr r5, [sp, #60]	 	@ get contents of PC;
 	sub r8, r5, #4
 .Lx2:	ldrt r0, [r8]			@ get actual instruction into r0
 emulate:
 	bl EmulateAll			@ emulate the instruction
    	cmp r0, #0			@ was emulation successful
-        moveq pc, r10			@ no, return failure
+        moveq pc, r4			@ no, return failure
 
 next:
 .Lx1:	ldrt r6, [r5], #4		@ get the next instruction and
@@ -99,10 +91,10 @@
         teqne r2, #0x0E000000
         movne pc, r9			@ return ok if not a fp insn
 
-        str r5, [r4, #60]		@ update PC copy in regs
+        str r5, [sp, #60]		@ update PC copy in regs
 
         mov r0, r6			@ save a copy
-        ldr r1, [r4, #64]		@ fetch the condition codes
+        ldr r1, [sp, #64]		@ fetch the condition codes
    	bl  checkCondition		@ check the condition
    	cmp r0, #0			@ r0 = 0 ==> condition failed
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/nwfpe/entry26.S linux/arch/arm/nwfpe/entry26.S
--- linux.orig/arch/arm/nwfpe/entry26.S	Thu Apr 12 02:02:27 2001
+++ linux/arch/arm/nwfpe/entry26.S	Tue May 28 22:39:22 2002
@@ -65,18 +65,8 @@
 
 	.globl	nwfpe_enter
 nwfpe_enter:
-	ldr	r4, =userRegisters
-	str	sp, [r4]		@ save pointer to user regs
-
-	mov	r10, sp, lsr #13	@ find workspace
-	mov	r10, r10, lsl #13
-	add	r10, r10, #TSS_FPESAVE
-
-	ldr	r4, =fpa11
-	str	r10, [r4]		@ store pointer to our state
-	mov	r4, sp			@ use r4 for local pointer
-
-	ldr	r5, [r4, #60]		@ get contents of PC
+	mov	sl, sp
+	ldr	r5, [sp, #60]		@ get contents of PC
 	bic	r5, r5, #0xfc000003
 	ldr	r0, [r5, #-4]		@ get actual instruction into r0
 	bl	EmulateAll		@ emulate the instruction
@@ -93,10 +83,10 @@
 	teqne	r2, #0x0E000000
 	bne	ret_from_exception	@ return ok if not a fp insn
 
-	ldr	r9, [r4, #60]		@ get new condition codes
+	ldr	r9, [sp, #60]		@ get new condition codes
 	and	r9, r9, #0xfc000003
 	orr	r7, r5, r9
-	str	r7, [r4, #60]		@ update PC copy in regs
+	str	r7, [sp, #60]		@ update PC copy in regs
 
 	mov	r0, r6			@ save a copy
 	mov	r1, r9			@ fetch the condition codes
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/nwfpe/extended_cpdo.c linux/arch/arm/nwfpe/extended_cpdo.c
--- linux.orig/arch/arm/nwfpe/extended_cpdo.c	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/nwfpe/extended_cpdo.c	Tue May 28 22:39:13 2002
@@ -19,9 +19,9 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
+#include "fpa11.h"
 #include "softfloat.h"
 #include "fpopcode.h"
-#include "fpa11.h"
 
 floatx80 floatx80_exp(floatx80 Fm);
 floatx80 floatx80_ln(floatx80 Fm);
@@ -157,8 +157,7 @@
 
       case RND_CODE:
       case URD_CODE:
-         fpa11->fpreg[Fd].fExtended = 
-             int32_to_floatx80(floatx80_to_int32(rFm));
+         fpa11->fpreg[Fd].fExtended = floatx80_round_to_int(rFm);
       break;
 
       case SQT_CODE:
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/nwfpe/fpa11.c linux/arch/arm/nwfpe/fpa11.c
--- linux.orig/arch/arm/nwfpe/fpa11.c	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/nwfpe/fpa11.c	Tue May 28 22:39:24 2002
@@ -19,14 +19,15 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-#include <asm/system.h>
-
 #include "fpa11.h"
+
 #include "fpopcode.h"
 
 #include "fpmodule.h"
 #include "fpmodule.inl"
 
+#include <asm/system.h>
+
 /* forward declarations */
 unsigned int EmulateCPDO(const unsigned int);
 unsigned int EmulateCPDT(const unsigned int);
@@ -56,6 +57,7 @@
 void SetRoundingMode(const unsigned int opcode)
 {
 #if MAINTAIN_FPCR
+   FPA11 *fpa11 = GET_FPA11();
    fpa11->fpcr &= ~MASK_ROUNDING_MODE;
 #endif   
    switch (opcode & MASK_ROUNDING_MODE)
@@ -94,6 +96,7 @@
 void SetRoundingPrecision(const unsigned int opcode)
 {
 #if MAINTAIN_FPCR
+   FPA11 *fpa11 = GET_FPA11();
    fpa11->fpcr &= ~MASK_ROUNDING_PRECISION;
 #endif   
    switch (opcode & MASK_ROUNDING_PRECISION)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/nwfpe/fpa11.h linux/arch/arm/nwfpe/fpa11.h
--- linux.orig/arch/arm/nwfpe/fpa11.h	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/nwfpe/fpa11.h	Tue May 28 22:39:26 2002
@@ -22,45 +22,67 @@
 #ifndef __FPA11_H__
 #define __FPA11_H__
 
-/* includes */
-#include "fpsr.h"		/* FP control and status register definitions */
-#include "softfloat.h"
+#define GET_FPA11() ((FPA11 *)(&current->thread.fpstate))
+
+/*
+ * The processes registers are always at the very top of the 8K
+ * stack+task struct.  Use the same method as 'current' uses to
+ * reach them.
+ */
+register unsigned int *user_registers asm("sl");
+
+#define GET_USERREG() (user_registers)
 
 /* Need task_struct */
 #include <linux/sched.h>
 
+/* includes */
+#include "fpsr.h"		/* FP control and status register definitions */
+#include "softfloat.h"
+
 #define		typeNone		0x00
 #define		typeSingle		0x01
 #define		typeDouble		0x02
 #define		typeExtended		0x03
 
+/*
+ * This must be no more and no less than 12 bytes.
+ */
 typedef union tagFPREG {
-   float32  fSingle;
-   float64  fDouble;
    floatx80 fExtended;
+   float64  fDouble;
+   float32  fSingle;
 } FPREG;
 
-/* FPA11 device model */
+/*
+ * FPA11 device model.
+ *
+ * This structure is exported to user space.  Do not re-order.
+ * Only add new stuff to the end, and do not change the size of
+ * any element.  Elements of this structure are used by user
+ * space, and must match struct user_fp in include/asm-arm/user.h.
+ * We include the byte offsets below for documentation purposes.
+ *
+ * The size of this structure and FPREG are checked by fpmodule.c
+ * on initialisation.  If the rules have been broken, NWFPE will
+ * not initialise.
+ */
 typedef struct tagFPA11 {
-  unsigned int *userRegisters;
-  FPREG fpreg[8];		/* 8 floating point registers */
-  FPSR fpsr;			/* floating point status register */
-  FPCR fpcr;			/* floating point control register */
-  unsigned char fType[8];	/* type of floating point value held in
-				   floating point registers.  One of none
-				   single, double or extended. */
-  int initflag;			/* this is special.  The kernel guarantees
-				   to set it to 0 when a thread is launched,
-				   so we can use it to detect whether this
-				   instance of the emulator needs to be
-				   initialised. */
+/*   0 */  FPREG fpreg[8];		/* 8 floating point registers */
+/*  96 */  FPSR fpsr;			/* floating point status register */
+/* 100 */  FPCR fpcr;			/* floating point control register */
+/* 104 */  unsigned char fType[8];	/* type of floating point value held in
+					   floating point registers.  One of none
+					   single, double or extended. */
+/* 112 */  int initflag;		/* this is special.  The kernel guarantees
+					   to set it to 0 when a thread is launched,
+					   so we can use it to detect whether this
+					   instance of the emulator needs to be
+					   initialised. */
 } FPA11;
 
 extern void resetFPA11(void);
 extern void SetRoundingMode(const unsigned int);
 extern void SetRoundingPrecision(const unsigned int);
-
-#define GET_FPA11() ((FPA11 *)(&current->thread.fpstate))
-#define GET_USERREG() (GET_FPA11()->userRegisters)
 
 #endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/nwfpe/fpa11_cpdt.c linux/arch/arm/nwfpe/fpa11_cpdt.c
--- linux.orig/arch/arm/nwfpe/fpa11_cpdt.c	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/nwfpe/fpa11_cpdt.c	Tue May 28 22:39:31 2002
@@ -20,9 +20,9 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
+#include "fpa11.h"
 #include "softfloat.h"
 #include "fpopcode.h"
-#include "fpa11.h"
 #include "fpmodule.h"
 #include "fpmodule.inl"
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/nwfpe/fpa11_cprt.c linux/arch/arm/nwfpe/fpa11_cprt.c
--- linux.orig/arch/arm/nwfpe/fpa11_cprt.c	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/nwfpe/fpa11_cprt.c	Tue May 28 22:39:17 2002
@@ -20,10 +20,10 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
+#include "fpa11.h"
 #include "milieu.h"
 #include "softfloat.h"
 #include "fpopcode.h"
-#include "fpa11.h"
 #include "fpa11.inl"
 #include "fpmodule.h"
 #include "fpmodule.inl"
@@ -82,8 +82,7 @@
    
    unsigned int nRc = 1;
    SetRoundingMode(opcode);
-   SetRoundingPrecision(opcode);
-   
+
    switch (opcode & MASK_ROUNDING_PRECISION)
    {
       case ROUND_SINGLE:
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/nwfpe/fpmodule.c linux/arch/arm/nwfpe/fpmodule.c
--- linux.orig/arch/arm/nwfpe/fpmodule.c	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/nwfpe/fpmodule.c	Tue May 28 22:39:26 2002
@@ -21,6 +21,8 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
+#include "fpa11.h"
+
 #include <linux/module.h>
 #include <linux/version.h>
 #include <linux/config.h>
@@ -36,7 +38,6 @@
 #include "softfloat.h"
 #include "fpopcode.h"
 #include "fpmodule.h"
-#include "fpa11.h"
 #include "fpa11.inl"
 
 /* kernel symbols required for signal handling */
@@ -83,6 +84,11 @@
 {
   if (sizeof(FPA11) > sizeof(union fp_state)) {
     printk(KERN_ERR "nwfpe: bad structure size\n");
+    return -EINVAL;
+  }
+
+  if (sizeof(FPREG) != 12) {
+    printk(KERN_ERR "nwfpe: bad register size\n");
     return -EINVAL;
   }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/nwfpe/fpopcode.c linux/arch/arm/nwfpe/fpopcode.c
--- linux.orig/arch/arm/nwfpe/fpopcode.c	Thu Apr 12 02:02:27 2001
+++ linux/arch/arm/nwfpe/fpopcode.c	Tue May 28 22:39:25 2002
@@ -19,10 +19,10 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
+#include "fpa11.h"
 #include "softfloat.h"
 #include "fpopcode.h"
 #include "fpsr.h"
-#include "fpa11.h"
 #include "fpmodule.h"
 #include "fpmodule.inl"
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/nwfpe/single_cpdo.c linux/arch/arm/nwfpe/single_cpdo.c
--- linux.orig/arch/arm/nwfpe/single_cpdo.c	Sun Aug 12 18:13:59 2001
+++ linux/arch/arm/nwfpe/single_cpdo.c	Tue May 28 22:39:25 2002
@@ -19,9 +19,9 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
+#include "fpa11.h"
 #include "softfloat.h"
 #include "fpopcode.h"
-#include "fpa11.h"
 
 float32 float32_exp(float32 Fm);
 float32 float32_ln(float32 Fm);
@@ -139,8 +139,7 @@
 
       case RND_CODE:
       case URD_CODE:
-         fpa11->fpreg[Fd].fSingle = 
-             int32_to_float32(float32_to_int32(rFm));
+         fpa11->fpreg[Fd].fSingle = float32_round_to_int(rFm);
       break;
 
       case SQT_CODE:
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/nwfpe/softfloat-specialize linux/arch/arm/nwfpe/softfloat-specialize
--- linux.orig/arch/arm/nwfpe/softfloat-specialize	Thu Jun 17 08:11:35 1999
+++ linux/arch/arm/nwfpe/softfloat-specialize	Tue May 28 22:39:31 2002
@@ -364,108 +364,3 @@
 }
 
 #endif
-
-#ifdef FLOAT128
-
-/*
--------------------------------------------------------------------------------
-The pattern for a default generated quadruple-precision NaN.  The `high' and
-`low' values hold the most- and least-significant bits, respectively.
--------------------------------------------------------------------------------
-*/
-#define float128_default_nan_high LIT64( 0xFFFFFFFFFFFFFFFF )
-#define float128_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
-
-/*
--------------------------------------------------------------------------------
-Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
-otherwise returns 0.
--------------------------------------------------------------------------------
-*/
-flag float128_is_nan( float128 a )
-{
-
-    return
-           ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
-        && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns 1 if the quadruple-precision floating-point value `a' is a
-signaling NaN; otherwise returns 0.
--------------------------------------------------------------------------------
-*/
-flag float128_is_signaling_nan( float128 a )
-{
-
-    return
-           ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
-        && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns the result of converting the quadruple-precision floating-point NaN
-`a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
-exception is raised.
--------------------------------------------------------------------------------
-*/
-static commonNaNT float128ToCommonNaN( float128 a )
-{
-    commonNaNT z;
-
-    if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
-    z.sign = a.high>>63;
-    shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
-    return z;
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns the result of converting the canonical NaN `a' to the quadruple-
-precision floating-point format.
--------------------------------------------------------------------------------
-*/
-static float128 commonNaNToFloat128( commonNaNT a )
-{
-    float128 z;
-
-    shift128Right( a.high, a.low, 16, &z.high, &z.low );
-    z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
-    return z;
-
-}
-
-/*
--------------------------------------------------------------------------------
-Takes two quadruple-precision floating-point values `a' and `b', one of
-which is a NaN, and returns the appropriate NaN result.  If either `a' or
-`b' is a signaling NaN, the invalid exception is raised.
--------------------------------------------------------------------------------
-*/
-static float128 propagateFloat128NaN( float128 a, float128 b )
-{
-    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
-
-    aIsNaN = float128_is_nan( a );
-    aIsSignalingNaN = float128_is_signaling_nan( a );
-    bIsNaN = float128_is_nan( b );
-    bIsSignalingNaN = float128_is_signaling_nan( b );
-    a.high |= LIT64( 0x0000800000000000 );
-    b.high |= LIT64( 0x0000800000000000 );
-    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
-    if ( aIsNaN ) {
-        return ( aIsSignalingNaN & bIsNaN ) ? b : a;
-    }
-    else {
-        return b;
-    }
-
-}
-
-#endif
-
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/nwfpe/softfloat.c linux/arch/arm/nwfpe/softfloat.c
--- linux.orig/arch/arm/nwfpe/softfloat.c	Tue Nov 28 01:07:59 2000
+++ linux/arch/arm/nwfpe/softfloat.c	Tue May 28 22:39:28 2002
@@ -28,6 +28,7 @@
 ===============================================================================
 */
 
+#include "fpa11.h"
 #include "milieu.h"
 #include "softfloat.h"
 
@@ -753,277 +754,6 @@
 
 #endif
 
-#ifdef FLOAT128
-
-/*
--------------------------------------------------------------------------------
-Returns the least-significant 64 fraction bits of the quadruple-precision
-floating-point value `a'.
--------------------------------------------------------------------------------
-*/
-INLINE bits64 extractFloat128Frac1( float128 a )
-{
-
-    return a.low;
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns the most-significant 48 fraction bits of the quadruple-precision
-floating-point value `a'.
--------------------------------------------------------------------------------
-*/
-INLINE bits64 extractFloat128Frac0( float128 a )
-{
-
-    return a.high & LIT64( 0x0000FFFFFFFFFFFF );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns the exponent bits of the quadruple-precision floating-point value
-`a'.
--------------------------------------------------------------------------------
-*/
-INLINE int32 extractFloat128Exp( float128 a )
-{
-
-    return ( a.high>>48 ) & 0x7FFF;
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns the sign bit of the quadruple-precision floating-point value `a'.
--------------------------------------------------------------------------------
-*/
-INLINE flag extractFloat128Sign( float128 a )
-{
-
-    return a.high>>63;
-
-}
-
-/*
--------------------------------------------------------------------------------
-Normalizes the subnormal quadruple-precision floating-point value
-represented by the denormalized significand formed by the concatenation of
-`aSig0' and `aSig1'.  The normalized exponent is stored at the location
-pointed to by `zExpPtr'.  The most significant 49 bits of the normalized
-significand are stored at the location pointed to by `zSig0Ptr', and the
-least significant 64 bits of the normalized significand are stored at the
-location pointed to by `zSig1Ptr'.
--------------------------------------------------------------------------------
-*/
-static void
- normalizeFloat128Subnormal(
-     bits64 aSig0,
-     bits64 aSig1,
-     int32 *zExpPtr,
-     bits64 *zSig0Ptr,
-     bits64 *zSig1Ptr
- )
-{
-    int8 shiftCount;
-
-    if ( aSig0 == 0 ) {
-        shiftCount = countLeadingZeros64( aSig1 ) - 15;
-        if ( shiftCount < 0 ) {
-            *zSig0Ptr = aSig1>>( - shiftCount );
-            *zSig1Ptr = aSig1<<( shiftCount & 63 );
-        }
-        else {
-            *zSig0Ptr = aSig1<<shiftCount;
-            *zSig1Ptr = 0;
-        }
-        *zExpPtr = - shiftCount - 63;
-    }
-    else {
-        shiftCount = countLeadingZeros64( aSig0 ) - 15;
-        shortShift128Left( aSig0, aSig1, shiftCount, zSig0Ptr, zSig1Ptr );
-        *zExpPtr = 1 - shiftCount;
-    }
-
-}
-
-/*
--------------------------------------------------------------------------------
-Packs the sign `zSign', the exponent `zExp', and the significand formed
-by the concatenation of `zSig0' and `zSig1' into a quadruple-precision
-floating-point value, returning the result.  After being shifted into the
-proper positions, the three fields `zSign', `zExp', and `zSig0' are simply
-added together to form the most significant 32 bits of the result.  This
-means that any integer portion of `zSig0' will be added into the exponent.
-Since a properly normalized significand will have an integer portion equal
-to 1, the `zExp' input should be 1 less than the desired result exponent
-whenever `zSig0' and `zSig1' concatenated form a complete, normalized
-significand.
--------------------------------------------------------------------------------
-*/
-INLINE float128
- packFloat128( flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 )
-{
-    float128 z;
-
-    z.low = zSig1;
-    z.high = ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<48 ) + zSig0;
-    return z;
-
-}
-
-/*
--------------------------------------------------------------------------------
-Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-and extended significand formed by the concatenation of `zSig0', `zSig1',
-and `zSig2', and returns the proper quadruple-precision floating-point value
-corresponding to the abstract input.  Ordinarily, the abstract value is
-simply rounded and packed into the quadruple-precision format, with the
-inexact exception raised if the abstract input cannot be represented
-exactly.  If the abstract value is too large, however, the overflow and
-inexact exceptions are raised and an infinity or maximal finite value is
-returned.  If the abstract value is too small, the input value is rounded to
-a subnormal number, and the underflow and inexact exceptions are raised if
-the abstract input cannot be represented exactly as a subnormal quadruple-
-precision floating-point number.
-    The input significand must be normalized or smaller.  If the input
-significand is not normalized, `zExp' must be 0; in that case, the result
-returned is a subnormal number, and it must not require rounding.  In the
-usual case that the input significand is normalized, `zExp' must be 1 less
-than the ``true'' floating-point exponent.  The handling of underflow and
-overflow follows the IEC/IEEE Standard for Binary Floating-point Arithmetic.
--------------------------------------------------------------------------------
-*/
-static float128
- roundAndPackFloat128(
-     flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1, bits64 zSig2 )
-{
-    int8 roundingMode;
-    flag roundNearestEven, increment, isTiny;
-
-    roundingMode = float_rounding_mode;
-    roundNearestEven = ( roundingMode == float_round_nearest_even );
-    increment = ( (sbits64) zSig2 < 0 );
-    if ( ! roundNearestEven ) {
-        if ( roundingMode == float_round_to_zero ) {
-            increment = 0;
-        }
-        else {
-            if ( zSign ) {
-                increment = ( roundingMode == float_round_down ) && zSig2;
-            }
-            else {
-                increment = ( roundingMode == float_round_up ) && zSig2;
-            }
-        }
-    }
-    if ( 0x7FFD <= (bits32) zExp ) {
-        if (    ( 0x7FFD < zExp )
-             || (    ( zExp == 0x7FFD )
-                  && eq128(
-                         LIT64( 0x0001FFFFFFFFFFFF ),
-                         LIT64( 0xFFFFFFFFFFFFFFFF ),
-                         zSig0,
-                         zSig1
-                     )
-                  && increment
-                )
-           ) {
-            float_raise( float_flag_overflow | float_flag_inexact );
-            if (    ( roundingMode == float_round_to_zero )
-                 || ( zSign && ( roundingMode == float_round_up ) )
-                 || ( ! zSign && ( roundingMode == float_round_down ) )
-               ) {
-                return
-                    packFloat128(
-                        zSign,
-                        0x7FFE,
-                        LIT64( 0x0000FFFFFFFFFFFF ),
-                        LIT64( 0xFFFFFFFFFFFFFFFF )
-                    );
-            }
-            return packFloat128( zSign, 0x7FFF, 0, 0 );
-        }
-        if ( zExp < 0 ) {
-            isTiny =
-                   ( float_detect_tininess == float_tininess_before_rounding )
-                || ( zExp < -1 )
-                || ! increment
-                || lt128(
-                       zSig0,
-                       zSig1,
-                       LIT64( 0x0001FFFFFFFFFFFF ),
-                       LIT64( 0xFFFFFFFFFFFFFFFF )
-                   );
-            shift128ExtraRightJamming(
-                zSig0, zSig1, zSig2, - zExp, &zSig0, &zSig1, &zSig2 );
-            zExp = 0;
-            if ( isTiny && zSig2 ) float_raise( float_flag_underflow );
-            if ( roundNearestEven ) {
-                increment = ( (sbits64) zSig2 < 0 );
-            }
-            else {
-                if ( zSign ) {
-                    increment = ( roundingMode == float_round_down ) && zSig2;
-                }
-                else {
-                    increment = ( roundingMode == float_round_up ) && zSig2;
-                }
-            }
-        }
-    }
-    if ( zSig2 ) float_exception_flags |= float_flag_inexact;
-    if ( increment ) {
-        add128( zSig0, zSig1, 0, 1, &zSig0, &zSig1 );
-        zSig1 &= ~ ( ( zSig2 + zSig2 == 0 ) & roundNearestEven );
-    }
-    else {
-        if ( ( zSig0 | zSig1 ) == 0 ) zExp = 0;
-    }
-    return packFloat128( zSign, zExp, zSig0, zSig1 );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Takes an abstract floating-point value having sign `zSign', exponent `zExp',
-and significand formed by the concatenation of `zSig0' and `zSig1', and
-returns the proper quadruple-precision floating-point value corresponding to
-the abstract input.  This routine is just like `roundAndPackFloat128' except
-that the input significand has fewer bits and does not have to be normalized
-in any way.  In all cases, `zExp' must be 1 less than the ``true'' floating-
-point exponent.
--------------------------------------------------------------------------------
-*/
-static float128
- normalizeRoundAndPackFloat128(
-     flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 )
-{
-    int8 shiftCount;
-    bits64 zSig2;
-
-    if ( zSig0 == 0 ) {
-        zSig0 = zSig1;
-        zSig1 = 0;
-        zExp -= 64;
-    }
-    shiftCount = countLeadingZeros64( zSig0 ) - 15;
-    if ( 0 <= shiftCount ) {
-        zSig2 = 0;
-        shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
-    }
-    else {
-        shift128ExtraRightJamming(
-            zSig0, zSig1, 0, - shiftCount, &zSig0, &zSig1, &zSig2 );
-    }
-    zExp -= shiftCount;
-    return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 );
-
-}
-
-#endif
-
 /*
 -------------------------------------------------------------------------------
 Returns the result of converting the 32-bit two's complement integer `a' to
@@ -1093,33 +823,6 @@
 
 #endif
 
-#ifdef FLOAT128
-
-/*
--------------------------------------------------------------------------------
-Returns the result of converting the 32-bit two's complement integer `a' to
-the quadruple-precision floating-point format.  The conversion is performed
-according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
--------------------------------------------------------------------------------
-*/
-float128 int32_to_float128( int32 a )
-{
-    flag zSign;
-    uint32 absA;
-    int8 shiftCount;
-    bits64 zSig0;
-
-    if ( a == 0 ) return packFloat128( 0, 0, 0, 0 );
-    zSign = ( a < 0 );
-    absA = zSign ? - a : a;
-    shiftCount = countLeadingZeros32( absA ) + 17;
-    zSig0 = absA;
-    return packFloat128( zSign, 0x402E - shiftCount, zSig0<<shiftCount, 0 );
-
-}
-
-#endif
-
 /*
 -------------------------------------------------------------------------------
 Returns the result of converting the single-precision floating-point value
@@ -1256,40 +959,6 @@
 
 #endif
 
-#ifdef FLOAT128
-
-/*
--------------------------------------------------------------------------------
-Returns the result of converting the single-precision floating-point value
-`a' to the double-precision floating-point format.  The conversion is
-performed according to the IEC/IEEE Standard for Binary Floating-point
-Arithmetic.
--------------------------------------------------------------------------------
-*/
-float128 float32_to_float128( float32 a )
-{
-    flag aSign;
-    int16 aExp;
-    bits32 aSig;
-
-    aSig = extractFloat32Frac( a );
-    aExp = extractFloat32Exp( a );
-    aSign = extractFloat32Sign( a );
-    if ( aExp == 0xFF ) {
-        if ( aSig ) return commonNaNToFloat128( float32ToCommonNaN( a ) );
-        return packFloat128( aSign, 0x7FFF, 0, 0 );
-    }
-    if ( aExp == 0 ) {
-        if ( aSig == 0 ) return packFloat128( aSign, 0, 0, 0 );
-        normalizeFloat32Subnormal( aSig, &aExp, &aSig );
-        --aExp;
-    }
-    return packFloat128( aSign, aExp + 0x3F80, ( (bits64) aSig )<<25, 0 );
-
-}
-
-#endif
-
 /*
 -------------------------------------------------------------------------------
 Rounds the single-precision floating-point value `a' to an integer, and
@@ -2183,41 +1852,6 @@
 
 #endif
 
-#ifdef FLOAT128
-
-/*
--------------------------------------------------------------------------------
-Returns the result of converting the double-precision floating-point value
-`a' to the quadruple-precision floating-point format.  The conversion is
-performed according to the IEC/IEEE Standard for Binary Floating-point
-Arithmetic.
--------------------------------------------------------------------------------
-*/
-float128 float64_to_float128( float64 a )
-{
-    flag aSign;
-    int16 aExp;
-    bits64 aSig, zSig0, zSig1;
-
-    aSig = extractFloat64Frac( a );
-    aExp = extractFloat64Exp( a );
-    aSign = extractFloat64Sign( a );
-    if ( aExp == 0x7FF ) {
-        if ( aSig ) return commonNaNToFloat128( float64ToCommonNaN( a ) );
-        return packFloat128( aSign, 0x7FFF, 0, 0 );
-    }
-    if ( aExp == 0 ) {
-        if ( aSig == 0 ) return packFloat128( aSign, 0, 0, 0 );
-        normalizeFloat64Subnormal( aSig, &aExp, &aSig );
-        --aExp;
-    }
-    shift128Right( aSig, 0, 4, &zSig0, &zSig1 );
-    return packFloat128( aSign, aExp + 0x3C00, zSig0, zSig1 );
-
-}
-
-#endif
-
 /*
 -------------------------------------------------------------------------------
 Rounds the double-precision floating-point value `a' to an integer, and
@@ -3029,35 +2663,6 @@
 
 }
 
-#ifdef FLOAT128
-
-/*
--------------------------------------------------------------------------------
-Returns the result of converting the extended double-precision floating-
-point value `a' to the quadruple-precision floating-point format.  The
-conversion is performed according to the IEC/IEEE Standard for Binary
-Floating-point Arithmetic.
--------------------------------------------------------------------------------
-*/
-float128 floatx80_to_float128( floatx80 a )
-{
-    flag aSign;
-    int16 aExp;
-    bits64 aSig, zSig0, zSig1;
-
-    aSig = extractFloatx80Frac( a );
-    aExp = extractFloatx80Exp( a );
-    aSign = extractFloatx80Sign( a );
-    if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) {
-        return commonNaNToFloat128( floatx80ToCommonNaN( a ) );
-    }
-    shift128Right( aSig<<1, 0, 16, &zSig0, &zSig1 );
-    return packFloat128( aSign, aExp, zSig0, zSig1 );
-
-}
-
-#endif
-
 /*
 -------------------------------------------------------------------------------
 Rounds the extended double-precision floating-point value `a' to an integer,
@@ -3822,1048 +3427,6 @@
         return
                aSign
             && (    ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
-                 != 0 );
-    }
-    return
-          aSign ? lt128( b.high, b.low, a.high, a.low )
-        : lt128( a.high, a.low, b.high, b.low );
-
-}
-
-#endif
-
-#ifdef FLOAT128
-
-/*
--------------------------------------------------------------------------------
-Returns the result of converting the quadruple-precision floating-point
-value `a' to the 32-bit two's complement integer format.  The conversion
-is performed according to the IEC/IEEE Standard for Binary Floating-point
-Arithmetic---which means in particular that the conversion is rounded
-according to the current rounding mode.  If `a' is a NaN, the largest
-positive integer is returned.  Otherwise, if the conversion overflows, the
-largest integer with the same sign as `a' is returned.
--------------------------------------------------------------------------------
-*/
-int32 float128_to_int32( float128 a )
-{
-    flag aSign;
-    int32 aExp, shiftCount;
-    bits64 aSig0, aSig1;
-
-    aSig1 = extractFloat128Frac1( a );
-    aSig0 = extractFloat128Frac0( a );
-    aExp = extractFloat128Exp( a );
-    aSign = extractFloat128Sign( a );
-    if ( ( aExp == 0x7FFF ) && ( aSig0 | aSig1 ) ) aSign = 0;
-    if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 );
-    aSig0 |= ( aSig1 != 0 );
-    shiftCount = 0x4028 - aExp;
-    if ( 0 < shiftCount ) shift64RightJamming( aSig0, shiftCount, &aSig0 );
-    return roundAndPackInt32( aSign, aSig0 );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns the result of converting the quadruple-precision floating-point
-value `a' to the 32-bit two's complement integer format.  The conversion
-is performed according to the IEC/IEEE Standard for Binary Floating-point
-Arithmetic, except that the conversion is always rounded toward zero.  If
-`a' is a NaN, the largest positive integer is returned.  Otherwise, if the
-conversion overflows, the largest integer with the same sign as `a' is
-returned.
--------------------------------------------------------------------------------
-*/
-int32 float128_to_int32_round_to_zero( float128 a )
-{
-    flag aSign;
-    int32 aExp, shiftCount;
-    bits64 aSig0, aSig1, savedASig;
-    int32 z;
-
-    aSig1 = extractFloat128Frac1( a );
-    aSig0 = extractFloat128Frac0( a );
-    aExp = extractFloat128Exp( a );
-    aSign = extractFloat128Sign( a );
-    aSig0 |= ( aSig1 != 0 );
-    shiftCount = 0x402F - aExp;
-    if ( shiftCount < 17 ) {
-        if ( ( aExp == 0x7FFF ) && aSig0 ) aSign = 0;
-        goto invalid;
-    }
-    else if ( 48 < shiftCount ) {
-        if ( aExp || aSig0 ) float_exception_flags |= float_flag_inexact;
-        return 0;
-    }
-    aSig0 |= LIT64( 0x0001000000000000 );
-    savedASig = aSig0;
-    aSig0 >>= shiftCount;
-    z = aSig0;
-    if ( aSign ) z = - z;
-    if ( ( z < 0 ) ^ aSign ) {
- invalid:
-        float_exception_flags |= float_flag_invalid;
-        return aSign ? 0x80000000 : 0x7FFFFFFF;
-    }
-    if ( ( aSig0<<shiftCount ) != savedASig ) {
-        float_exception_flags |= float_flag_inexact;
-    }
-    return z;
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns the result of converting the quadruple-precision floating-point
-value `a' to the single-precision floating-point format.  The conversion
-is performed according to the IEC/IEEE Standard for Binary Floating-point
-Arithmetic.
--------------------------------------------------------------------------------
-*/
-float32 float128_to_float32( float128 a )
-{
-    flag aSign;
-    int32 aExp;
-    bits64 aSig0, aSig1;
-    bits32 zSig;
-
-    aSig1 = extractFloat128Frac1( a );
-    aSig0 = extractFloat128Frac0( a );
-    aExp = extractFloat128Exp( a );
-    aSign = extractFloat128Sign( a );
-    if ( aExp == 0x7FFF ) {
-        if ( aSig0 | aSig1 ) {
-            return commonNaNToFloat32( float128ToCommonNaN( a ) );
-        }
-        return packFloat32( aSign, 0xFF, 0 );
-    }
-    aSig0 |= ( aSig1 != 0 );
-    shift64RightJamming( aSig0, 18, &aSig0 );
-    zSig = aSig0;
-    if ( aExp || zSig ) {
-        zSig |= 0x40000000;
-        aExp -= 0x3F81;
-    }
-    return roundAndPackFloat32( aSign, aExp, zSig );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns the result of converting the quadruple-precision floating-point
-value `a' to the double-precision floating-point format.  The conversion
-is performed according to the IEC/IEEE Standard for Binary Floating-point
-Arithmetic.
--------------------------------------------------------------------------------
-*/
-float64 float128_to_float64( float128 a )
-{
-    flag aSign;
-    int32 aExp;
-    bits64 aSig0, aSig1;
-
-    aSig1 = extractFloat128Frac1( a );
-    aSig0 = extractFloat128Frac0( a );
-    aExp = extractFloat128Exp( a );
-    aSign = extractFloat128Sign( a );
-    if ( aExp == 0x7FFF ) {
-        if ( aSig0 | aSig1 ) {
-            return commonNaNToFloat64( float128ToCommonNaN( a ) );
-        }
-        return packFloat64( aSign, 0x7FF, 0 );
-    }
-    shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 );
-    aSig0 |= ( aSig1 != 0 );
-    if ( aExp || aSig0 ) {
-        aSig0 |= LIT64( 0x4000000000000000 );
-        aExp -= 0x3C01;
-    }
-    return roundAndPackFloat64( aSign, aExp, aSig0 );
-
-}
-
-#ifdef FLOATX80
-
-/*
--------------------------------------------------------------------------------
-Returns the result of converting the quadruple-precision floating-point
-value `a' to the extended double-precision floating-point format.  The
-conversion is performed according to the IEC/IEEE Standard for Binary
-Floating-point Arithmetic.
--------------------------------------------------------------------------------
-*/
-floatx80 float128_to_floatx80( float128 a )
-{
-    flag aSign;
-    int32 aExp;
-    bits64 aSig0, aSig1;
-
-    aSig1 = extractFloat128Frac1( a );
-    aSig0 = extractFloat128Frac0( a );
-    aExp = extractFloat128Exp( a );
-    aSign = extractFloat128Sign( a );
-    if ( aExp == 0x7FFF ) {
-        if ( aSig0 | aSig1 ) {
-            return commonNaNToFloatx80( float128ToCommonNaN( a ) );
-        }
-        return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
-    }
-    if ( aExp == 0 ) {
-        if ( ( aSig0 | aSig1 ) == 0 ) return packFloatx80( aSign, 0, 0 );
-        normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
-    }
-    else {
-        aSig0 |= LIT64( 0x0001000000000000 );
-    }
-    shortShift128Left( aSig0, aSig1, 15, &aSig0, &aSig1 );
-    return roundAndPackFloatx80( 80, aSign, aExp, aSig0, aSig1 );
-
-}
-
-#endif
-
-/*
--------------------------------------------------------------------------------
-Rounds the quadruple-precision floating-point value `a' to an integer, and
-returns the result as a quadruple-precision floating-point value.  The
-operation is performed according to the IEC/IEEE Standard for Binary
-Floating-point Arithmetic.
--------------------------------------------------------------------------------
-*/
-float128 float128_round_to_int( float128 a )
-{
-    flag aSign;
-    int32 aExp;
-    bits64 lastBitMask, roundBitsMask;
-    int8 roundingMode;
-    float128 z;
-
-    aExp = extractFloat128Exp( a );
-    if ( 0x402F <= aExp ) {
-        if ( 0x406F <= aExp ) {
-            if (    ( aExp == 0x7FFF )
-                 && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) )
-               ) {
-                return propagateFloat128NaN( a, a );
-            }
-            return a;
-        }
-        lastBitMask = 1;
-        lastBitMask = ( lastBitMask<<( 0x406E - aExp ) )<<1;
-        roundBitsMask = lastBitMask - 1;
-        z = a;
-        roundingMode = float_rounding_mode;
-        if ( roundingMode == float_round_nearest_even ) {
-            if ( lastBitMask ) {
-                add128( z.high, z.low, 0, lastBitMask>>1, &z.high, &z.low );
-                if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask;
-            }
-            else {
-                if ( (sbits64) z.low < 0 ) {
-                    ++z.high;
-                    if ( (bits64) ( z.low<<1 ) == 0 ) z.high &= ~1;
-                }
-            }
-        }
-        else if ( roundingMode != float_round_to_zero ) {
-            if (   extractFloat128Sign( z )
-                 ^ ( roundingMode == float_round_up ) ) {
-                add128( z.high, z.low, 0, roundBitsMask, &z.high, &z.low );
-            }
-        }
-        z.low &= ~ roundBitsMask;
-    }
-    else {
-        if ( aExp <= 0x3FFE ) {
-            if ( ( ( (bits64) ( a.high<<1 ) ) | a.low ) == 0 ) return a;
-            float_exception_flags |= float_flag_inexact;
-            aSign = extractFloat128Sign( a );
-            switch ( float_rounding_mode ) {
-             case float_round_nearest_even:
-                if (    ( aExp == 0x3FFE )
-                     && (   extractFloat128Frac0( a )
-                          | extractFloat128Frac1( a ) )
-                   ) {
-                    return packFloat128( aSign, 0x3FFF, 0, 0 );
-                }
-                break;
-             case float_round_down:
-                return
-                      aSign ? packFloat128( 1, 0x3FFF, 0, 0 )
-                    : packFloat128( 0, 0, 0, 0 );
-             case float_round_up:
-                return
-                      aSign ? packFloat128( 1, 0, 0, 0 )
-                    : packFloat128( 0, 0x3FFF, 0, 0 );
-            }
-            return packFloat128( aSign, 0, 0, 0 );
-        }
-        lastBitMask = 1;
-        lastBitMask <<= 0x402F - aExp;
-        roundBitsMask = lastBitMask - 1;
-        z.low = 0;
-        z.high = a.high;
-        roundingMode = float_rounding_mode;
-        if ( roundingMode == float_round_nearest_even ) {
-            z.high += lastBitMask>>1;
-            if ( ( ( z.high & roundBitsMask ) | a.low ) == 0 ) {
-                z.high &= ~ lastBitMask;
-            }
-        }
-        else if ( roundingMode != float_round_to_zero ) {
-            if (   extractFloat128Sign( z )
-                 ^ ( roundingMode == float_round_up ) ) {
-                z.high |= ( a.low != 0 );
-                z.high += roundBitsMask;
-            }
-        }
-        z.high &= ~ roundBitsMask;
-    }
-    if ( ( z.low != a.low ) || ( z.high != a.high ) ) {
-        float_exception_flags |= float_flag_inexact;
-    }
-    return z;
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns the result of adding the absolute values of the quadruple-precision
-floating-point values `a' and `b'.  If `zSign' is true, the sum is negated
-before being returned.  `zSign' is ignored if the result is a NaN.  The
-addition is performed according to the IEC/IEEE Standard for Binary
-Floating-point Arithmetic.
--------------------------------------------------------------------------------
-*/
-static float128 addFloat128Sigs( float128 a, float128 b, flag zSign )
-{
-    int32 aExp, bExp, zExp;
-    bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2;
-    int32 expDiff;
-
-    aSig1 = extractFloat128Frac1( a );
-    aSig0 = extractFloat128Frac0( a );
-    aExp = extractFloat128Exp( a );
-    bSig1 = extractFloat128Frac1( b );
-    bSig0 = extractFloat128Frac0( b );
-    bExp = extractFloat128Exp( b );
-    expDiff = aExp - bExp;
-    if ( 0 < expDiff ) {
-        if ( aExp == 0x7FFF ) {
-            if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b );
-            return a;
-        }
-        if ( bExp == 0 ) {
-            --expDiff;
-        }
-        else {
-            bSig0 |= LIT64( 0x0001000000000000 );
-        }
-        shift128ExtraRightJamming(
-            bSig0, bSig1, 0, expDiff, &bSig0, &bSig1, &zSig2 );
-        zExp = aExp;
-    }
-    else if ( expDiff < 0 ) {
-        if ( bExp == 0x7FFF ) {
-            if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b );
-            return packFloat128( zSign, 0x7FFF, 0, 0 );
-        }
-        if ( aExp == 0 ) {
-            ++expDiff;
-        }
-        else {
-            aSig0 |= LIT64( 0x0001000000000000 );
-        }
-        shift128ExtraRightJamming(
-            aSig0, aSig1, 0, - expDiff, &aSig0, &aSig1, &zSig2 );
-        zExp = bExp;
-    }
-    else {
-        if ( aExp == 0x7FFF ) {
-            if ( aSig0 | aSig1 | bSig0 | bSig1 ) {
-                return propagateFloat128NaN( a, b );
-            }
-            return a;
-        }
-        add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
-        if ( aExp == 0 ) return packFloat128( zSign, 0, zSig0, zSig1 );
-        zSig2 = 0;
-        zSig0 |= LIT64( 0x0002000000000000 );
-        zExp = aExp;
-        goto shiftRight1;
-    }
-    aSig0 |= LIT64( 0x0001000000000000 );
-    add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
-    --zExp;
-    if ( zSig0 < LIT64( 0x0002000000000000 ) ) goto roundAndPack;
-    ++zExp;
- shiftRight1:
-    shift128ExtraRightJamming(
-        zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 );
- roundAndPack:
-    return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns the result of subtracting the absolute values of the quadruple-
-precision floating-point values `a' and `b'.  If `zSign' is true, the
-difference is negated before being returned.  `zSign' is ignored if the
-result is a NaN.  The subtraction is performed according to the IEC/IEEE
-Standard for Binary Floating-point Arithmetic.
--------------------------------------------------------------------------------
-*/
-static float128 subFloat128Sigs( float128 a, float128 b, flag zSign )
-{
-    int32 aExp, bExp, zExp;
-    bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1;
-    int32 expDiff;
-    float128 z;
-
-    aSig1 = extractFloat128Frac1( a );
-    aSig0 = extractFloat128Frac0( a );
-    aExp = extractFloat128Exp( a );
-    bSig1 = extractFloat128Frac1( b );
-    bSig0 = extractFloat128Frac0( b );
-    bExp = extractFloat128Exp( b );
-    expDiff = aExp - bExp;
-    shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 );
-    shortShift128Left( bSig0, bSig1, 14, &bSig0, &bSig1 );
-    if ( 0 < expDiff ) goto aExpBigger;
-    if ( expDiff < 0 ) goto bExpBigger;
-    if ( aExp == 0x7FFF ) {
-        if ( aSig0 | aSig1 | bSig0 | bSig1 ) {
-            return propagateFloat128NaN( a, b );
-        }
-        float_raise( float_flag_invalid );
-        z.low = float128_default_nan_low;
-        z.high = float128_default_nan_high;
-        return z;
-    }
-    if ( aExp == 0 ) {
-        aExp = 1;
-        bExp = 1;
-    }
-    if ( bSig0 < aSig0 ) goto aBigger;
-    if ( aSig0 < bSig0 ) goto bBigger;
-    if ( bSig1 < aSig1 ) goto aBigger;
-    if ( aSig1 < bSig1 ) goto bBigger;
-    return packFloat128( float_rounding_mode == float_round_down, 0, 0, 0 );
- bExpBigger:
-    if ( bExp == 0x7FFF ) {
-        if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b );
-        return packFloat128( zSign ^ 1, 0x7FFF, 0, 0 );
-    }
-    if ( aExp == 0 ) {
-        ++expDiff;
-    }
-    else {
-        aSig0 |= LIT64( 0x4000000000000000 );
-    }
-    shift128RightJamming( aSig0, aSig1, - expDiff, &aSig0, &aSig1 );
-    bSig0 |= LIT64( 0x4000000000000000 );
- bBigger:
-    sub128( bSig0, bSig1, aSig0, aSig1, &zSig0, &zSig1 );
-    zExp = bExp;
-    zSign ^= 1;
-    goto normalizeRoundAndPack;
- aExpBigger:
-    if ( aExp == 0x7FFF ) {
-        if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b );
-        return a;
-    }
-    if ( bExp == 0 ) {
-        --expDiff;
-    }
-    else {
-        bSig0 |= LIT64( 0x4000000000000000 );
-    }
-    shift128RightJamming( bSig0, bSig1, expDiff, &bSig0, &bSig1 );
-    aSig0 |= LIT64( 0x4000000000000000 );
- aBigger:
-    sub128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
-    zExp = aExp;
- normalizeRoundAndPack:
-    --zExp;
-    return normalizeRoundAndPackFloat128( zSign, zExp - 14, zSig0, zSig1 );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns the result of adding the quadruple-precision floating-point values
-`a' and `b'.  The operation is performed according to the IEC/IEEE Standard
-for Binary Floating-point Arithmetic.
--------------------------------------------------------------------------------
-*/
-float128 float128_add( float128 a, float128 b )
-{
-    flag aSign, bSign;
-
-    aSign = extractFloat128Sign( a );
-    bSign = extractFloat128Sign( b );
-    if ( aSign == bSign ) {
-        return addFloat128Sigs( a, b, aSign );
-    }
-    else {
-        return subFloat128Sigs( a, b, aSign );
-    }
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns the result of subtracting the quadruple-precision floating-point
-values `a' and `b'.  The operation is performed according to the IEC/IEEE
-Standard for Binary Floating-point Arithmetic.
--------------------------------------------------------------------------------
-*/
-float128 float128_sub( float128 a, float128 b )
-{
-    flag aSign, bSign;
-
-    aSign = extractFloat128Sign( a );
-    bSign = extractFloat128Sign( b );
-    if ( aSign == bSign ) {
-        return subFloat128Sigs( a, b, aSign );
-    }
-    else {
-        return addFloat128Sigs( a, b, aSign );
-    }
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns the result of multiplying the quadruple-precision floating-point
-values `a' and `b'.  The operation is performed according to the IEC/IEEE
-Standard for Binary Floating-point Arithmetic.
--------------------------------------------------------------------------------
-*/
-float128 float128_mul( float128 a, float128 b )
-{
-    flag aSign, bSign, zSign;
-    int32 aExp, bExp, zExp;
-    bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2, zSig3;
-    float128 z;
-
-    aSig1 = extractFloat128Frac1( a );
-    aSig0 = extractFloat128Frac0( a );
-    aExp = extractFloat128Exp( a );
-    aSign = extractFloat128Sign( a );
-    bSig1 = extractFloat128Frac1( b );
-    bSig0 = extractFloat128Frac0( b );
-    bExp = extractFloat128Exp( b );
-    bSign = extractFloat128Sign( b );
-    zSign = aSign ^ bSign;
-    if ( aExp == 0x7FFF ) {
-        if (    ( aSig0 | aSig1 )
-             || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) {
-            return propagateFloat128NaN( a, b );
-        }
-        if ( ( bExp | bSig0 | bSig1 ) == 0 ) goto invalid;
-        return packFloat128( zSign, 0x7FFF, 0, 0 );
-    }
-    if ( bExp == 0x7FFF ) {
-        if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b );
-        if ( ( aExp | aSig0 | aSig1 ) == 0 ) {
- invalid:
-            float_raise( float_flag_invalid );
-            z.low = float128_default_nan_low;
-            z.high = float128_default_nan_high;
-            return z;
-        }
-        return packFloat128( zSign, 0x7FFF, 0, 0 );
-    }
-    if ( aExp == 0 ) {
-        if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 );
-        normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
-    }
-    if ( bExp == 0 ) {
-        if ( ( bSig0 | bSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 );
-        normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
-    }
-    zExp = aExp + bExp - 0x4000;
-    aSig0 |= LIT64( 0x0001000000000000 );
-    shortShift128Left( bSig0, bSig1, 16, &bSig0, &bSig1 );
-    mul128To256( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1, &zSig2, &zSig3 );
-    add128( zSig0, zSig1, aSig0, aSig1, &zSig0, &zSig1 );
-    zSig2 |= ( zSig3 != 0 );
-    if ( LIT64( 0x0002000000000000 ) <= zSig0 ) {
-        shift128ExtraRightJamming(
-            zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 );
-        ++zExp;
-    }
-    return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns the result of dividing the quadruple-precision floating-point value
-`a' by the corresponding value `b'.  The operation is performed according to
-the IEC/IEEE Standard for Binary Floating-point Arithmetic.
--------------------------------------------------------------------------------
-*/
-float128 float128_div( float128 a, float128 b )
-{
-    flag aSign, bSign, zSign;
-    int32 aExp, bExp, zExp;
-    bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2;
-    bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3;
-    float128 z;
-
-    aSig1 = extractFloat128Frac1( a );
-    aSig0 = extractFloat128Frac0( a );
-    aExp = extractFloat128Exp( a );
-    aSign = extractFloat128Sign( a );
-    bSig1 = extractFloat128Frac1( b );
-    bSig0 = extractFloat128Frac0( b );
-    bExp = extractFloat128Exp( b );
-    bSign = extractFloat128Sign( b );
-    zSign = aSign ^ bSign;
-    if ( aExp == 0x7FFF ) {
-        if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b );
-        if ( bExp == 0x7FFF ) {
-            if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b );
-            goto invalid;
-        }
-        return packFloat128( zSign, 0x7FFF, 0, 0 );
-    }
-    if ( bExp == 0x7FFF ) {
-        if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b );
-        return packFloat128( zSign, 0, 0, 0 );
-    }
-    if ( bExp == 0 ) {
-        if ( ( bSig0 | bSig1 ) == 0 ) {
-            if ( ( aExp | aSig0 | aSig1 ) == 0 ) {
- invalid:
-                float_raise( float_flag_invalid );
-                z.low = float128_default_nan_low;
-                z.high = float128_default_nan_high;
-                return z;
-            }
-            float_raise( float_flag_divbyzero );
-            return packFloat128( zSign, 0x7FFF, 0, 0 );
-        }
-        normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
-    }
-    if ( aExp == 0 ) {
-        if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 );
-        normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
-    }
-    zExp = aExp - bExp + 0x3FFD;
-    shortShift128Left(
-        aSig0 | LIT64( 0x0001000000000000 ), aSig1, 15, &aSig0, &aSig1 );
-    shortShift128Left(
-        bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 );
-    if ( le128( bSig0, bSig1, aSig0, aSig1 ) ) {
-        shift128Right( aSig0, aSig1, 1, &aSig0, &aSig1 );
-        ++zExp;
-    }
-    zSig0 = estimateDiv128To64( aSig0, aSig1, bSig0 );
-    mul128By64To192( bSig0, bSig1, zSig0, &term0, &term1, &term2 );
-    sub192( aSig0, aSig1, 0, term0, term1, term2, &rem0, &rem1, &rem2 );
-    while ( (sbits64) rem0 < 0 ) {
-        --zSig0;
-        add192( rem0, rem1, rem2, 0, bSig0, bSig1, &rem0, &rem1, &rem2 );
-    }
-    zSig1 = estimateDiv128To64( rem1, rem2, bSig0 );
-    if ( ( zSig1 & 0x3FFF ) <= 4 ) {
-        mul128By64To192( bSig0, bSig1, zSig1, &term1, &term2, &term3 );
-        sub192( rem1, rem2, 0, term1, term2, term3, &rem1, &rem2, &rem3 );
-        while ( (sbits64) rem1 < 0 ) {
-            --zSig1;
-            add192( rem1, rem2, rem3, 0, bSig0, bSig1, &rem1, &rem2, &rem3 );
-        }
-        zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
-    }
-    shift128ExtraRightJamming( zSig0, zSig1, 0, 15, &zSig0, &zSig1, &zSig2 );
-    return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns the remainder of the quadruple-precision floating-point value `a'
-with respect to the corresponding value `b'.  The operation is performed
-according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
--------------------------------------------------------------------------------
-*/
-float128 float128_rem( float128 a, float128 b )
-{
-    flag aSign, bSign, zSign;
-    int32 aExp, bExp, expDiff;
-    bits64 aSig0, aSig1, bSig0, bSig1;
-    bits64 q, term0, term1, term2, allZero, alternateASig0, alternateASig1;
-    bits64 sigMean1;
-    sbits64 sigMean0;
-    float128 z;
-
-    aSig1 = extractFloat128Frac1( a );
-    aSig0 = extractFloat128Frac0( a );
-    aExp = extractFloat128Exp( a );
-    aSign = extractFloat128Sign( a );
-    bSig1 = extractFloat128Frac1( b );
-    bSig0 = extractFloat128Frac0( b );
-    bExp = extractFloat128Exp( b );
-    bSign = extractFloat128Sign( b );
-    if ( aExp == 0x7FFF ) {
-        if (    ( aSig0 | aSig1 )
-             || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) {
-            return propagateFloat128NaN( a, b );
-        }
-        goto invalid;
-    }
-    if ( bExp == 0x7FFF ) {
-        if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b );
-        return a;
-    }
-    if ( bExp == 0 ) {
-        if ( ( bSig0 | bSig1 ) == 0 ) {
- invalid:
-            float_raise( float_flag_invalid );
-            z.low = float128_default_nan_low;
-            z.high = float128_default_nan_high;
-            return z;
-        }
-        normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
-    }
-    if ( aExp == 0 ) {
-        if ( ( aSig0 | aSig1 ) == 0 ) return a;
-        normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
-    }
-    expDiff = aExp - bExp;
-    if ( expDiff < -1 ) return a;
-    shortShift128Left(
-        aSig0 | LIT64( 0x0001000000000000 ),
-        aSig1,
-        15 - ( expDiff < 0 ),
-        &aSig0,
-        &aSig1
-    );
-    shortShift128Left(
-        bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 );
-    q = le128( bSig0, bSig1, aSig0, aSig1 );
-    if ( q ) sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 );
-    expDiff -= 64;
-    while ( 0 < expDiff ) {
-        q = estimateDiv128To64( aSig0, aSig1, bSig0 );
-        q = ( 4 < q ) ? q - 4 : 0;
-        mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 );
-        shortShift192Left( term0, term1, term2, 61, &term1, &term2, &allZero );
-        shortShift128Left( aSig0, aSig1, 61, &aSig0, &allZero );
-        sub128( aSig0, 0, term1, term2, &aSig0, &aSig1 );
-        expDiff -= 61;
-    }
-    if ( -64 < expDiff ) {
-        q = estimateDiv128To64( aSig0, aSig1, bSig0 );
-        q = ( 4 < q ) ? q - 4 : 0;
-        q >>= - expDiff;
-        shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 );
-        expDiff += 52;
-        if ( expDiff < 0 ) {
-            shift128Right( aSig0, aSig1, - expDiff, &aSig0, &aSig1 );
-        }
-        else {
-            shortShift128Left( aSig0, aSig1, expDiff, &aSig0, &aSig1 );
-        }
-        mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 );
-        sub128( aSig0, aSig1, term1, term2, &aSig0, &aSig1 );
-    }
-    else {
-        shift128Right( aSig0, aSig1, 12, &aSig0, &aSig1 );
-        shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 );
-    }
-    do {
-        alternateASig0 = aSig0;
-        alternateASig1 = aSig1;
-        ++q;
-        sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 );
-    } while ( 0 <= (sbits64) aSig0 );
-    add128(
-        aSig0, aSig1, alternateASig0, alternateASig1, &sigMean0, &sigMean1 );
-    if (    ( sigMean0 < 0 )
-         || ( ( ( sigMean0 | sigMean1 ) == 0 ) && ( q & 1 ) ) ) {
-        aSig0 = alternateASig0;
-        aSig1 = alternateASig1;
-    }
-    zSign = ( (sbits64) aSig0 < 0 );
-    if ( zSign ) sub128( 0, 0, aSig0, aSig1, &aSig0, &aSig1 );
-    return
-        normalizeRoundAndPackFloat128( aSign ^ zSign, bExp - 4, aSig0, aSig1 );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns the square root of the quadruple-precision floating-point value `a'.
-The operation is performed according to the IEC/IEEE Standard for Binary
-Floating-point Arithmetic.
--------------------------------------------------------------------------------
-*/
-float128 float128_sqrt( float128 a )
-{
-    flag aSign;
-    int32 aExp, zExp;
-    bits64 aSig0, aSig1, zSig0, zSig1, zSig2;
-    bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3;
-    bits64 shiftedRem0, shiftedRem1;
-    float128 z;
-
-    aSig1 = extractFloat128Frac1( a );
-    aSig0 = extractFloat128Frac0( a );
-    aExp = extractFloat128Exp( a );
-    aSign = extractFloat128Sign( a );
-    if ( aExp == 0x7FFF ) {
-        if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, a );
-        if ( ! aSign ) return a;
-        goto invalid;
-    }
-    if ( aSign ) {
-        if ( ( aExp | aSig0 | aSig1 ) == 0 ) return a;
- invalid:
-        float_raise( float_flag_invalid );
-        z.low = float128_default_nan_low;
-        z.high = float128_default_nan_high;
-        return z;
-    }
-    if ( aExp == 0 ) {
-        if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( 0, 0, 0, 0 );
-        normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
-    }
-    zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFE;
-    aSig0 |= LIT64( 0x0001000000000000 );
-    zSig0 = estimateSqrt32( aExp, aSig0>>17 );
-    zSig0 <<= 31;
-    shortShift128Left( aSig0, aSig1, 13 - ( aExp & 1 ), &aSig0, &aSig1 );
-    zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0 ) + zSig0 + 4;
-    if ( 0 <= (sbits64) zSig0 ) zSig0 = LIT64( 0xFFFFFFFFFFFFFFFF );
-    shortShift128Left( aSig0, aSig1, 2, &aSig0, &aSig1 );
-    mul64To128( zSig0, zSig0, &term0, &term1 );
-    sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 );
-    while ( (sbits64) rem0 < 0 ) {
-        --zSig0;
-        shortShift128Left( 0, zSig0, 1, &term0, &term1 );
-        term1 |= 1;
-        add128( rem0, rem1, term0, term1, &rem0, &rem1 );
-    }
-    shortShift128Left( rem0, rem1, 63, &shiftedRem0, &shiftedRem1 );
-    zSig1 = estimateDiv128To64( shiftedRem0, shiftedRem1, zSig0 );
-    if ( ( zSig1 & 0x3FFF ) <= 5 ) {
-        if ( zSig1 == 0 ) zSig1 = 1;
-        mul64To128( zSig0, zSig1, &term1, &term2 );
-        shortShift128Left( term1, term2, 1, &term1, &term2 );
-        sub128( rem1, 0, term1, term2, &rem1, &rem2 );
-        mul64To128( zSig1, zSig1, &term2, &term3 );
-        sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 );
-        while ( (sbits64) rem1 < 0 ) {
-            --zSig1;
-            shortShift192Left( 0, zSig0, zSig1, 1, &term1, &term2, &term3 );
-            term3 |= 1;
-            add192(
-                rem1, rem2, rem3, term1, term2, term3, &rem1, &rem2, &rem3 );
-        }
-        zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
-    }
-    shift128ExtraRightJamming( zSig0, zSig1, 0, 15, &zSig0, &zSig1, &zSig2 );
-    return roundAndPackFloat128( 0, zExp, zSig0, zSig1, zSig2 );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns 1 if the quadruple-precision floating-point value `a' is equal to
-the corresponding value `b', and 0 otherwise.  The comparison is performed
-according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
--------------------------------------------------------------------------------
-*/
-flag float128_eq( float128 a, float128 b )
-{
-
-    if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
-              && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
-         || (    ( extractFloat128Exp( b ) == 0x7FFF )
-              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
-       ) {
-        if (    float128_is_signaling_nan( a )
-             || float128_is_signaling_nan( b ) ) {
-            float_raise( float_flag_invalid );
-        }
-        return 0;
-    }
-    return
-           ( a.low == b.low )
-        && (    ( a.high == b.high )
-             || (    ( a.low == 0 )
-                  && ( (bits64) ( ( a.high | b.high )<<1 ) == 0 ) )
-           );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns 1 if the quadruple-precision floating-point value `a' is less than
-or equal to the corresponding value `b', and 0 otherwise.  The comparison
-is performed according to the IEC/IEEE Standard for Binary Floating-point
-Arithmetic.
--------------------------------------------------------------------------------
-*/
-flag float128_le( float128 a, float128 b )
-{
-    flag aSign, bSign;
-
-    if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
-              && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
-         || (    ( extractFloat128Exp( b ) == 0x7FFF )
-              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
-       ) {
-        float_raise( float_flag_invalid );
-        return 0;
-    }
-    aSign = extractFloat128Sign( a );
-    bSign = extractFloat128Sign( b );
-    if ( aSign != bSign ) {
-        return
-               aSign
-            || (    ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
-                 == 0 );
-    }
-    return
-          aSign ? le128( b.high, b.low, a.high, a.low )
-        : le128( a.high, a.low, b.high, b.low );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns 1 if the quadruple-precision floating-point value `a' is less than
-the corresponding value `b', and 0 otherwise.  The comparison is performed
-according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
--------------------------------------------------------------------------------
-*/
-flag float128_lt( float128 a, float128 b )
-{
-    flag aSign, bSign;
-
-    if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
-              && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
-         || (    ( extractFloat128Exp( b ) == 0x7FFF )
-              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
-       ) {
-        float_raise( float_flag_invalid );
-        return 0;
-    }
-    aSign = extractFloat128Sign( a );
-    bSign = extractFloat128Sign( b );
-    if ( aSign != bSign ) {
-        return
-               aSign
-            && (    ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
-                 != 0 );
-    }
-    return
-          aSign ? lt128( b.high, b.low, a.high, a.low )
-        : lt128( a.high, a.low, b.high, b.low );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns 1 if the quadruple-precision floating-point value `a' is equal to
-the corresponding value `b', and 0 otherwise.  The invalid exception is
-raised if either operand is a NaN.  Otherwise, the comparison is performed
-according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
--------------------------------------------------------------------------------
-*/
-flag float128_eq_signaling( float128 a, float128 b )
-{
-
-    if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
-              && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
-         || (    ( extractFloat128Exp( b ) == 0x7FFF )
-              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
-       ) {
-        float_raise( float_flag_invalid );
-        return 0;
-    }
-    return
-           ( a.low == b.low )
-        && (    ( a.high == b.high )
-             || (    ( a.low == 0 )
-                  && ( (bits64) ( ( a.high | b.high )<<1 ) == 0 ) )
-           );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns 1 if the quadruple-precision floating-point value `a' is less than
-or equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs do not
-cause an exception.  Otherwise, the comparison is performed according to the
-IEC/IEEE Standard for Binary Floating-point Arithmetic.
--------------------------------------------------------------------------------
-*/
-flag float128_le_quiet( float128 a, float128 b )
-{
-    flag aSign, bSign;
-
-    if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
-              && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
-         || (    ( extractFloat128Exp( b ) == 0x7FFF )
-              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
-       ) {
-        if (    float128_is_signaling_nan( a )
-             || float128_is_signaling_nan( b ) ) {
-            float_raise( float_flag_invalid );
-        }
-        return 0;
-    }
-    aSign = extractFloat128Sign( a );
-    bSign = extractFloat128Sign( b );
-    if ( aSign != bSign ) {
-        return
-               aSign
-            || (    ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
-                 == 0 );
-    }
-    return
-          aSign ? le128( b.high, b.low, a.high, a.low )
-        : le128( a.high, a.low, b.high, b.low );
-
-}
-
-/*
--------------------------------------------------------------------------------
-Returns 1 if the quadruple-precision floating-point value `a' is less than
-the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
-exception.  Otherwise, the comparison is performed according to the IEC/IEEE
-Standard for Binary Floating-point Arithmetic.
--------------------------------------------------------------------------------
-*/
-flag float128_lt_quiet( float128 a, float128 b )
-{
-    flag aSign, bSign;
-
-    if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
-              && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
-         || (    ( extractFloat128Exp( b ) == 0x7FFF )
-              && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
-       ) {
-        if (    float128_is_signaling_nan( a )
-             || float128_is_signaling_nan( b ) ) {
-            float_raise( float_flag_invalid );
-        }
-        return 0;
-    }
-    aSign = extractFloat128Sign( a );
-    bSign = extractFloat128Sign( b );
-    if ( aSign != bSign ) {
-        return
-               aSign
-            && (    ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
                  != 0 );
     }
     return
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/nwfpe/softfloat.h linux/arch/arm/nwfpe/softfloat.h
--- linux.orig/arch/arm/nwfpe/softfloat.h	Thu Jun 17 08:11:35 1999
+++ linux/arch/arm/nwfpe/softfloat.h	Tue May 28 22:39:16 2002
@@ -37,12 +37,10 @@
 The macro `FLOATX80' must be defined to enable the extended double-precision
 floating-point format `floatx80'.  If this macro is not defined, the
 `floatx80' type will not be defined, and none of the functions that either
-input or output the `floatx80' type will be defined.  The same applies to
-the `FLOAT128' macro and the quadruple-precision format `float128'.
+input or output the `floatx80' type will be defined.
 -------------------------------------------------------------------------------
 */
 #define FLOATX80
-/* #define FLOAT128 */
 
 /*
 -------------------------------------------------------------------------------
@@ -51,17 +49,10 @@
 */
 typedef unsigned long int float32;
 typedef unsigned long long float64;
-#ifdef FLOATX80
 typedef struct {
     unsigned short high;
     unsigned long long low;
 } floatx80;
-#endif
-#ifdef FLOAT128
-typedef struct {
-    unsigned long long high, low;
-} float128;
-#endif
 
 /*
 -------------------------------------------------------------------------------
@@ -131,9 +122,6 @@
 #ifdef FLOATX80
 floatx80 int32_to_floatx80( signed int );
 #endif
-#ifdef FLOAT128
-float128 int32_to_float128( signed int );
-#endif
 
 /*
 -------------------------------------------------------------------------------
@@ -146,9 +134,6 @@
 #ifdef FLOATX80
 floatx80 float32_to_floatx80( float32 );
 #endif
-#ifdef FLOAT128
-float128 float32_to_float128( float32 );
-#endif
 
 /*
 -------------------------------------------------------------------------------
@@ -181,9 +166,6 @@
 #ifdef FLOATX80
 floatx80 float64_to_floatx80( float64 );
 #endif
-#ifdef FLOAT128
-float128 float64_to_float128( float64 );
-#endif
 
 /*
 -------------------------------------------------------------------------------
@@ -216,9 +198,6 @@
 signed int floatx80_to_int32_round_to_zero( floatx80 );
 float32 floatx80_to_float32( floatx80 );
 float64 floatx80_to_float64( floatx80 );
-#ifdef FLOAT128
-float128 floatx80_to_float128( floatx80 );
-#endif
 
 /*
 -------------------------------------------------------------------------------
@@ -247,43 +226,6 @@
 char floatx80_le_quiet( floatx80, floatx80 );
 char floatx80_lt_quiet( floatx80, floatx80 );
 char floatx80_is_signaling_nan( floatx80 );
-
-#endif
-
-#ifdef FLOAT128
-
-/*
--------------------------------------------------------------------------------
-Software IEC/IEEE quadruple-precision conversion routines.
--------------------------------------------------------------------------------
-*/
-signed int float128_to_int32( float128 );
-signed int float128_to_int32_round_to_zero( float128 );
-float32 float128_to_float32( float128 );
-float64 float128_to_float64( float128 );
-#ifdef FLOATX80
-floatx80 float128_to_floatx80( float128 );
-#endif
-
-/*
--------------------------------------------------------------------------------
-Software IEC/IEEE quadruple-precision operations.
--------------------------------------------------------------------------------
-*/
-float128 float128_round_to_int( float128 );
-float128 float128_add( float128, float128 );
-float128 float128_sub( float128, float128 );
-float128 float128_mul( float128, float128 );
-float128 float128_div( float128, float128 );
-float128 float128_rem( float128, float128 );
-float128 float128_sqrt( float128 );
-char float128_eq( float128, float128 );
-char float128_le( float128, float128 );
-char float128_lt( float128, float128 );
-char float128_eq_signaling( float128, float128 );
-char float128_le_quiet( float128, float128 );
-char float128_lt_quiet( float128, float128 );
-char float128_is_signaling_nan( float128 );
 
 #endif
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/tools/Makefile linux/arch/arm/tools/Makefile
--- linux.orig/arch/arm/tools/Makefile	Thu Oct 11 16:04:57 2001
+++ linux/arch/arm/tools/Makefile	Tue May 28 22:39:14 2002
@@ -15,13 +15,17 @@
 # what we want.  We do this in several stages so make picks up on
 # any errors that occur along the way.
 
-$(TOPDIR)/include/asm-arm/constants.h: constants-hdr getconstants.c
-	$(CC) $(CFLAGS) -S -o - getconstants.c > $@.tmp.1
+constants.h: constants-hdr getconstants.c
+	$(CC) $(CFLAGS) -S -o $@.tmp.1 getconstants.c
 	sed 's/^\(#define .* \)[#$$]\(.*\)/\1\2/;/^#define/!d' $@.tmp.1 > $@.tmp.2
-	cat constants-hdr $@.tmp.2 > $@.tmp
-	cmp $@.tmp $@ >/dev/null 2>&1 || mv $@.tmp $@
+	cat constants-hdr $@.tmp.2 > $@
 	$(RM) $@.tmp*
 
+# Only update include/asm-arm/constants.h when it has actually changed.
+
+$(TOPDIR)/include/asm-arm/constants.h: constants.h
+	cmp constants.h $@ >/dev/null 2>&1 || cp -p constants.h $@
+
 # Build our dependencies, and then generate the constants and
 # mach-types header files.  If we do it now, mkdep will pick
 # the dependencies up later on when it runs through the other
@@ -29,7 +33,7 @@
 
 dep:
 	$(TOPDIR)/scripts/mkdep $(CFLAGS) $(EXTRA_CFLAGS) -- getconstants.c |\
-	 sed s,getconstants.o,$(TOPDIR)/include/asm-arm/constants.h, > .depend
+	 sed s,getconstants.o,constants.h, > .depend
 	$(MAKE) all
 
 .PHONY:	all dep
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/arm/tools/mach-types linux/arch/arm/tools/mach-types
--- linux.orig/arch/arm/tools/mach-types	Fri Nov  9 21:58:02 2001
+++ linux/arch/arm/tools/mach-types	Tue May 28 22:39:27 2002
@@ -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: Fri Oct 26 17:37:13 2001
+# Last update: Sat Mar 16 15:56:27 2002
 #
 # machine_is_xxx	CONFIG_xxxx		MACH_TYPE_xxx		number
 #
@@ -118,10 +118,10 @@
 cdb89712		ARCH_CDB89712		CDB89712		107
 graphicsmaster		SA1100_GRAPHICSMASTER	GRAPHICSMASTER		108
 adsbitsy		SA1100_ADSBITSY		ADSBITSY		109
-cotulla_idp		ARCH_COTULLA_IDP	COTULLA_IDP		110
+pxa_idp			ARCH_PXA_IDP		PXA_IDP			110
 plce			ARCH_PLCE		PLCE			111
 pt_system3		SA1100_PT_SYSTEM3	PT_SYSTEM3		112
-medalb			ARCH_MEDALB		MEDALB			113
+murphy			ARCH_MEDALB		MEDALB			113
 eagle			ARCH_EAGLE		EAGLE			114
 dsc21			ARCH_DSC21		DSC21			115
 dsc24			ARCH_DSC24		DSC24			116
@@ -137,3 +137,44 @@
 elroy			SA1100_ELROY		ELROY			126
 gms720			ARCH_GMS720		GMS720			127
 s24x			ARCH_S24X		S24X			128
+jtel_clep7312		ARCH_JTEL_CLEP7312	JTEL_CLEP7312		129
+cx821xx			ARCH_CX821XX		CX821XX			130
+edb7312			ARCH_EDB7312		EDB7312			131
+bsa1110			SA1100_BSA1110		BSA1110			132
+powerpin		ARCH_POWERPIN		POWERPIN		133
+openarm			ARCH_OPENARM		OPENARM			134
+whitechapel		SA1100_WHITECHAPEL	WHITECHAPEL		135
+h3100			SA1100_H3100		H3100			136
+h3800			SA1100_H3800		H3800			137
+blue_v1			ARCH_BLUE_V1		BLUE_V1			138
+pxa_cerf		ARCH_PXA_CERF		PXA_CERF		139
+arm7tevb		ARCH_ARM7TEVB		ARM7TEVB		140
+d7400			ARCH_D7400		D7400			141
+piranha			ARCH_PIRANHA		PIRANHA			142
+sbcamelot		SA1100_SBCAMELOT	SBCAMELOT		143
+kings			SA1100_KINGS		KINGS			144
+smdk2400		ARCH_SMDK2400		SMDK2400		145
+collie			ARCH_COLLIE		COLLIE			146
+idr			ARCH_IDR		IDR			147
+badge4			SA1100_BADGE4		BADGE4			148
+webnet			ARCH_WEBNET		WEBNET			149
+d7300			SA1100_D7300		D7300			150
+cep			SA1100_CEP		CEP			151
+fortunet		ARCH_FORTUNET		FORTUNET		152
+vc547x			ARCH_VC547X		VC547X			153
+filewalker		SA1100_FILEWALKER	FILEWALKER		154
+netgateway		SA1100_NETGATEWAY	NETGATEWAY		155
+symbol2800		SA1100_SYMBOL2800	SYMBOL2800		156
+suns			SA1100_SUNS		SUNS			157
+frodo			SA1100_FRODO		FRODO			158
+ms301			SA1100_MACH_TYTE_MS301	MACH_TYTE_MS301		159
+mx1ads			ARCH_MX1ADS		MX1ADS			160
+h7201			ARCH_H7201		H7201			161
+h7202			ARCH_H7202		H7202			162
+amico			ARCH_AMICO		AMICO			163
+iam			SA1100_IAM		IAM			164
+tt530			SA1100_TT530		TT530			165
+sam2400			ARCH_SAM2400		SAM2400			166
+jornada56x		ARCH_JORNADA56X		JORNADA56X		167
+active			SA1100_ACTIVE		ACTIVE			168
+iq80321			ARCH_IQ80321		IQ80321			169
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/cris/Makefile linux/arch/cris/Makefile
--- linux.orig/arch/cris/Makefile	Mon Feb 25 19:37:52 2002
+++ linux/arch/cris/Makefile	Tue May 28 22:39:27 2002
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.26 2001/11/16 17:42:17 pkj Exp $
+# $Id: Makefile,v 1.27 2002/03/08 13:08:50 bjornw Exp $
 # cris/Makefile
 #
 # This file is included by the global makefile so that you can add your own
@@ -29,9 +29,9 @@
               -e s/@CONFIG_ETRAX_DRAM_SIZE_M@/$(CONFIG_ETRAX_DRAM_SIZE)/ \
               < $(LD_SCRIPT) > $(LD_SCRIPT).tmp; \
      else true; \
-     fi && $(CROSS_COMPILE)gcc -mlinux -nostdlib
+     fi && $(CROSS_COMPILE)ld -mcrislinux
 
-LINKFLAGS = -mlinux -T $(LD_SCRIPT).tmp
+LINKFLAGS = -T $(LD_SCRIPT).tmp
 
 # objcopy is used to make binary images from the resulting linked file
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/cris/defconfig linux/arch/cris/defconfig
--- linux.orig/arch/cris/defconfig	Fri Nov  9 21:58:02 2001
+++ linux/arch/cris/defconfig	Tue May 28 22:39:21 2002
@@ -99,6 +99,7 @@
 CONFIG_MTD_CFI=y
 # CONFIG_MTD_CFI_INTELEXT is not set
 CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_OBSOLETE_CHIPS=y
 CONFIG_MTD_AMDSTD=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/cris/drivers/Config.in linux/arch/cris/drivers/Config.in
--- linux.orig/arch/cris/drivers/Config.in	Fri Nov  9 21:58:02 2001
+++ linux/arch/cris/drivers/Config.in	Tue May 28 22:39:19 2002
@@ -143,6 +143,7 @@
 	define_bool CONFIG_MTD_CFI_INTELEXT n
 	define_bool CONFIG_MTD_CFI_AMDSTD y
 
+	define_bool CONFIG_MTD_OBSOLETE_CHIPS y
 	define_bool CONFIG_MTD_AMDSTD y
 
 	define_bool CONFIG_MTD_CHAR y
@@ -178,7 +179,7 @@
 bool 'ARTPEC-1 support' CONFIG_JULIETTE
 
 if [ "$CONFIG_JULIETTE" = "y" ]; then
-   source arch/cris/drivers/juliette/Config.in
+
 fi
 
 bool 'USB host' CONFIG_ETRAX_USB_HOST
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/cris/drivers/axisflashmap.c linux/arch/cris/drivers/axisflashmap.c
--- linux.orig/arch/cris/drivers/axisflashmap.c	Mon Feb 25 19:37:52 2002
+++ linux/arch/cris/drivers/axisflashmap.c	Tue May 28 22:39:30 2002
@@ -1,7 +1,7 @@
 /*
  * Physical mapping layer for MTD using the Axis partitiontable format
  *
- * Copyright (c) 2001 Axis Communications AB
+ * Copyright (c) 2001, 2002 Axis Communications AB
  *
  * This file is under the GPL.
  *
@@ -11,6 +11,27 @@
  * partition split defined below.
  *
  * $Log: axisflashmap.c,v $
+ * Revision 1.23  2002/05/13 12:12:28  johana
+ * Allow compile without CONFIG_MTD_MTDRAM but warn at compiletime and
+ * be informative at runtime.
+ *
+ * Revision 1.22  2002/05/13 10:24:44  johana
+ * Added #if checks on MTDRAM CONFIG
+ *
+ * Revision 1.21  2002/05/06 16:05:20  johana
+ * Removed debug printout.
+ *
+ * Revision 1.20  2002/05/06 16:03:00  johana
+ * No more cramfs as root hack in generic code.
+ * It's handled by axisflashmap using mtdram.
+ *
+ * Revision 1.19  2002/03/15 17:10:28  bjornw
+ * Changed comment about cached access since we changed this before
+ *
+ * Revision 1.18  2002/03/05 17:06:15  jonashg
+ * Try amd_flash probe before cfi_probe since amd_flash driver can handle two
+ * (or more) flash chips of different model and the cfi driver cannot.
+ *
  * Revision 1.17  2001/11/12 19:42:38  pkj
  * Fixed compiler warnings.
  *
@@ -80,6 +101,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/partitions.h>
+#include <linux/mtd/mtdram.h>
 
 #include <asm/axisflashmap.h>
 #include <asm/mmu.h>
@@ -106,9 +128,8 @@
 /* 
  * Map driver
  *
- * Ok this is the scoop - we need to access the flash both with and without
- * the cache - without when doing all the fancy flash interfacing, and with
- * when we do actual copying because otherwise it will be slow like molasses.
+ * We run into tricky coherence situations if we mix cached with uncached
+ * accesses to we use the uncached version here.
  */
 
 static __u8 flash_read8(struct map_info *map, unsigned long ofs)
@@ -239,6 +260,7 @@
 static int __init
 init_axis_flash(void)
 {
+	int err = 0;
 	int pidx = 0;
 	struct partitiontable_head *ptable_head;
 	struct partitiontable_entry *ptable;
@@ -247,14 +269,13 @@
 
 	printk(KERN_NOTICE "Axis flash mapping: %x at %lx\n",
 	       WINDOW_SIZE, FLASH_CACHED_ADDR);
-
-#ifdef CONFIG_MTD_CFI
-	mymtd = (struct mtd_info *)do_map_probe("cfi_probe", &axis_map);
+#ifdef CONFIG_MTD_AMDSTD
+	mymtd = (struct mtd_info *)do_map_probe("amd_flash", &axis_map);
 #endif
 
-#ifdef CONFIG_MTD_AMDSTD
+#ifdef CONFIG_MTD_CFI
 	if (!mymtd) {
-		mymtd = (struct mtd_info *)do_map_probe("amd_flash", &axis_map);
+		mymtd = (struct mtd_info *)do_map_probe("cfi_probe", &axis_map);
 	}
 #endif
 
@@ -333,8 +354,8 @@
 
 	if (use_default_ptable) {
 		printk(" Using default partition table\n");
-		return add_mtd_partitions(mymtd, axis_default_partitions,
-					  NUM_DEFAULT_PARTITIONS);
+		err = add_mtd_partitions(mymtd, axis_default_partitions,
+		                         NUM_DEFAULT_PARTITIONS);
 	} else {
 		if (romfs_in_flash) {
 			axis_partitions[pidx].name = "romfs";
@@ -348,8 +369,39 @@
 			       axis_partitions[pidx].size);
 			pidx++;
 		}
-		return add_mtd_partitions(mymtd, axis_partitions, pidx);
-	}		
+
+		err = add_mtd_partitions(mymtd, axis_partitions, pidx);
+	}
+	if (!err && !romfs_in_flash) {
+#ifdef CONFIG_MTD_MTDRAM
+		/* Allocate, initialise and forget the mtd ram struct
+		 * when booting from RAM
+		 */
+		struct mtd_info *romfs_mtd = (struct mtd_info *)kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
+		printk("MTD RAM device romfs_start: 0x%08lX len %lu\n",
+		       romfs_start, romfs_length);
+
+#if (CONFIG_MTDRAM_TOTAL_SIZE != 0) || (CONFIG_MTDRAM_ABS_POS != 0)
+#error "You must set CONFIG_MTDRAM_TOTAL_SIZE and CONFIG_MTDRAM_ABS_POS to 0"
+#endif
+		err = mtdram_init_device(romfs_mtd, (void*)romfs_start, 
+		                         romfs_length, "romfs in RAM");
+#else
+#warning ######################################
+#warning # You must enable CONFIG_MTD_MTDRAM  #
+#warning # with TOTAL_SIZE 0 and ABS_POS 0 to # 
+#warning # be able to boot with cramfs in RAM #
+#warning ######################################
+/* Maybe overkill to save these bytes in non debug builds, but let's do it..
+ * (No point in printing if we don't have a debug port anyway...)
+ */
+#ifndef CONFIG_ETRAX_DEBUG_PORT_NULL
+		printk("## Can't mount romfs in RAM using MTDRAM.\n");
+		printk("## You must enable MTD_MTDRAM with TOTAL_SIZE 0 and ABS_POS 0\n");
+#endif
+#endif /* CONFIG_MTD_MTDRAM */
+	}
+	return err;
 }
 
 /* This adds the above to the kernels init-call chain */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/cris/drivers/bluetooth/Makefile linux/arch/cris/drivers/bluetooth/Makefile
--- linux.orig/arch/cris/drivers/bluetooth/Makefile	Thu Jan  1 00:00:00 1970
+++ linux/arch/cris/drivers/bluetooth/Makefile	Tue May 28 22:39:29 2002
@@ -0,0 +1,26 @@
+include $(APPS)/Rules.elinux
+
+all:
+
+install:	src/bluetooth.c include/btcommon.h
+	ln -sfn ../../arch/cris/drivers/bluetooth/include ../../../../include/linux/bluetooth
+	if ! grep arch/cris/drivers/bluetooth/src/Config.in ../Config.in; then \
+	  echo '' >> ../Config.in; \
+	  echo '# The following if statement was added by arch/cris/drivers/bluetooth/Makefile' >> ../Config.in; \
+	  echo 'if [ "$$CONFIG_ETRAX_SERIAL" = "y" ]; then' >> ../Config.in; \
+	  echo '  source arch/cris/drivers/bluetooth/src/Config.in' >> ../Config.in; \
+	  echo 'fi' >> ../Config.in; \
+	fi
+	if ! grep bluetooth/src/bt.o ../Makefile; then \
+	  perl -pi -e "s:include:\# The following two lines were added by arch/cris/drivers/bluetooth/Makefile\nobj-\\\$$(CONFIG_BLUETOOTH)                 += bluetooth/src/bt.o\nsubdir-\\\$$(CONFIG_BLUETOOTH)              += bluetooth/src\n\ninclude:" ../Makefile; \
+	fi
+
+clean:
+
+src/bluetooth.c:
+	@echo "You must install the OpenBT src directory before install can be done here!"
+	@exit 1
+
+include/btcommon.h:
+	@echo "You must install the OpenBT include directory before install can be done here!"
+	@exit 1
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/cris/drivers/ds1302.c linux/arch/cris/drivers/ds1302.c
--- linux.orig/arch/cris/drivers/ds1302.c	Wed Jul  4 18:50:38 2001
+++ linux/arch/cris/drivers/ds1302.c	Tue May 28 22:39:30 2002
@@ -7,6 +7,9 @@
 *! Functions exported: ds1302_readreg, ds1302_writereg, ds1302_init, get_rtc_status
 *!
 *! $Log: ds1302.c,v $
+*! Revision 1.12  2002/04/10 15:35:25  johana
+*! Moved probe function closer to init function and marked it __init.
+*!
 *! 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.
 *!
@@ -82,7 +85,7 @@
 *!
 *! (C) Copyright 1999, 2000, 2001  Axis Communications AB, LUND, SWEDEN
 *!
-*! $Id: ds1302.c,v 1.11 2001/06/14 12:35:52 jonashg Exp $
+*! $Id: ds1302.c,v 1.12 2002/04/10 15:35:25 johana Exp $
 *!
 *!***************************************************************************/
 
@@ -228,54 +231,6 @@
 	stop();
 }
 
-/* Probe for the chip by writing something to its RAM and try reading it back. */
-
-#define MAGIC_PATTERN 0x42
-
-static int
-ds1302_probe(void) 
-{
-	int retval, res; 
-
-	TK_RST_DIR(1);
-	TK_SCL_DIR(1);
-	TK_SDA_DIR(0);
-	
-	/* Try to talk to timekeeper. */
-
-	ds1302_wenable();  
-	start();
-	out_byte(0xc0); /* write RAM byte 0 */	
-	out_byte(MAGIC_PATTERN); /* write something magic */
-	start();
-	out_byte(0xc1); /* read RAM byte 0 */
-
-	if((res = in_byte()) == MAGIC_PATTERN) {
-		char buf[100];
-		stop();
-		ds1302_wdisable();
-		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",
-#else
-		       "PB",
-#endif
-		       CONFIG_ETRAX_DS1302_RSTBIT);
-                get_rtc_status(buf);
-                printk(buf);
-		retval = 1;
-	} else {
-		stop();
-		printk("%s: RTC not found.\n", ds1302_name);
-		retval = 0;
-	}
-
-	return retval;
-}
 
 
 /* Read a byte from the selected register in the DS1302. */
@@ -479,6 +434,56 @@
         owner:          THIS_MODULE,
         ioctl:          rtc_ioctl,	
 }; 
+
+/* Probe for the chip by writing something to its RAM and try reading it back. */
+
+#define MAGIC_PATTERN 0x42
+
+static int __init
+ds1302_probe(void) 
+{
+	int retval, res; 
+
+	TK_RST_DIR(1);
+	TK_SCL_DIR(1);
+	TK_SDA_DIR(0);
+	
+	/* Try to talk to timekeeper. */
+
+	ds1302_wenable();  
+	start();
+	out_byte(0xc0); /* write RAM byte 0 */	
+	out_byte(MAGIC_PATTERN); /* write something magic */
+	start();
+	out_byte(0xc1); /* read RAM byte 0 */
+
+	if((res = in_byte()) == MAGIC_PATTERN) {
+		char buf[100];
+		stop();
+		ds1302_wdisable();
+		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",
+#else
+		       "PB",
+#endif
+		       CONFIG_ETRAX_DS1302_RSTBIT);
+                get_rtc_status(buf);
+                printk(buf);
+		retval = 1;
+	} else {
+		stop();
+		printk("%s: RTC not found.\n", ds1302_name);
+		retval = 0;
+	}
+
+	return retval;
+}
+
 
 /* Just probe for the RTC and register the device to handle the ioctl needed. */
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/cris/drivers/ethernet.c linux/arch/cris/drivers/ethernet.c
--- linux.orig/arch/cris/drivers/ethernet.c	Mon Feb 25 19:37:52 2002
+++ linux/arch/cris/drivers/ethernet.c	Tue May 28 22:39:26 2002
@@ -1,12 +1,52 @@
-/* $Id: ethernet.c,v 1.22 2002/01/30 07:48:22 matsfg Exp $
+/* $Id: ethernet.c,v 1.30 2002/05/07 18:50:08 johana Exp $
  *
  * e100net.c: A network driver for the ETRAX 100LX network controller.
  *
- * Copyright (c) 1998-2001 Axis Communications AB.
+ * Copyright (c) 1998-2002 Axis Communications AB.
  *
  * The outline of this driver comes from skeleton.c.
  *
  * $Log: ethernet.c,v $
+ * Revision 1.30  2002/05/07 18:50:08  johana
+ * Correct spelling in comments.
+ *
+ * Revision 1.29  2002/05/06 05:38:49  starvik
+ * Performance improvements:
+ *    Large packets are not copied (breakpoint set to 256 bytes)
+ *    The cache bug workaround is delayed until half of the receive list
+ *      has been used
+ *    Added transmit list
+ *    Transmit interrupts are only enabled when transmit queue is full
+ *
+ * Revision 1.28.2.1  2002/04/30 08:15:51  starvik
+ * Performance improvements:
+ *   Large packets are not copied (breakpoint set to 256 bytes)
+ *   The cache bug workaround is delayed until half of the receive list
+ *     has been used.
+ *   Added transmit list
+ *   Transmit interrupts are only enabled when transmit queue is full
+ *
+ * Revision 1.28  2002/04/22 11:47:21  johana
+ * Fix according to 2.4.19-pre7. time_after/time_before and
+ * missing end of comment.
+ * The patch has a typo for ethernet.c in e100_clear_network_leds(),
+ *  that is fixed here.
+ *
+ * Revision 1.27  2002/04/12 11:55:11  bjornw
+ * Added TODO
+ *
+ * Revision 1.26  2002/03/15 17:11:02  bjornw
+ * Use prepare_rx_descriptor after the CPU has touched the receiving descs
+ *
+ * Revision 1.25  2002/03/08 13:07:53  bjornw
+ * Unnecessary spinlock removed
+ *
+ * Revision 1.24  2002/02/20 12:57:43  fredriks
+ * Replaced MIN() with min().
+ *
+ * Revision 1.23  2002/02/20 10:58:14  fredriks
+ * Strip the Ethernet checksum (4 bytes) before forwarding a frame to upper layers.
+ *
  * Revision 1.22  2002/01/30 07:48:22  matsfg
  * Initiate R_NETWORK_TR_CTRL
  *
@@ -127,7 +167,6 @@
 //#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
@@ -154,6 +193,11 @@
 	spinlock_t lock;
 };
 
+typedef struct etrax_eth_descr
+{
+	etrax_dma_descr descr;
+	struct sk_buff* skb;
+} etrax_eth_descr;
 
 /* Duplex settings */
 enum duplex
@@ -165,8 +209,6 @@
 
 /* Dma descriptors etc. */
 
-#define RX_BUF_SIZE 32768
-
 #define MAX_MEDIA_DATA_SIZE 1518
 
 #define MIN_PACKET_LEN      46
@@ -207,9 +249,17 @@
 #define NO_NETWORK_ACTIVITY 0
 #define NETWORK_ACTIVITY    1
 
-#define RX_DESC_BUF_SIZE   256
-#define NBR_OF_RX_DESC     (RX_BUF_SIZE / \
-                            RX_DESC_BUF_SIZE)
+#define NBR_OF_RX_DESC     64
+#define NBR_OF_TX_DESC     256
+
+/* Large packets are sent directly to upper layers while small packets are */
+/* copied (to reduce memory waste). The following constant decides the breakpoint */
+#define RX_COPYBREAK 256
+
+/* Due to a chip bug we need to flush the cache when descriptors are returned */
+/* to the DMA. To decrease performance impact we return descriptors in chunks. */
+/* The following constant determines the number of descriptors to return. */
+#define RX_QUEUE_THRESHOLD  NBR_OF_RX_DESC/2
 
 #define GET_BIT(bit,val)   (((val) >> (bit)) & 0x01)
 
@@ -219,17 +269,17 @@
 #define SETS(var, reg, field, val) var = (var & ~IO_MASK(##reg##, field)) | \
 					  IO_STATE(##reg##, field, val)
 
-static etrax_dma_descr *myNextRxDesc;  /* Points to the next descriptor to
+static etrax_eth_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_eth_descr *myLastRxDesc;  /* The last processed descriptor */
+static etrax_eth_descr *myPrevRxDesc;  /* The descriptor right before myNextRxDesc */
 
-static etrax_dma_descr RxDescList[NBR_OF_RX_DESC] __attribute__ ((aligned(4)));
-static etrax_dma_descr TxDesc __attribute__ ((aligned(4)));
+static etrax_eth_descr RxDescList[NBR_OF_RX_DESC] __attribute__ ((aligned(32)));
 
-static struct sk_buff *tx_skb;
+static etrax_eth_descr* myFirstTxDesc; /* First packet not yet sent */
+static etrax_eth_descr* myLastTxDesc;  /* End of send queue */
+static etrax_eth_descr* myNextTxDesc;  /* Next descriptor to use */
+static etrax_eth_descr TxDescList[NBR_OF_TX_DESC] __attribute__ ((aligned(32)));
 
 static unsigned int network_rec_config_shadow = 0;
 
@@ -240,6 +290,7 @@
 static int current_speed_selection; /* Speed selected by user */
 static int led_next_time;
 static int led_active;
+static int rx_queue_len;
 
 /* Duplex */
 static struct timer_list duplex_timer;
@@ -295,7 +346,6 @@
 etrax_ethernet_init(struct net_device *dev)
 {
 	int i;
-	int anOffset = 0;
 
 	printk("ETRAX 100LX 10/100MBit ethernet v2.0 (c) 2000-2001 Axis Communications AB\n");
 
@@ -348,28 +398,44 @@
 
 	/* 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;
+	for (i = 0; i < NBR_OF_RX_DESC; i++) {
+		RxDescList[i].skb = dev_alloc_skb(MAX_MEDIA_DATA_SIZE);
+		RxDescList[i].descr.ctrl   = 0;
+		RxDescList[i].descr.sw_len = MAX_MEDIA_DATA_SIZE;
+		RxDescList[i].descr.next   = virt_to_phys(&RxDescList[i + 1]);
+		RxDescList[i].descr.buf    = virt_to_phys(RxDescList[i].skb->data);
+		RxDescList[i].descr.status = 0;
+		RxDescList[i].descr.hw_len = 0;
+             
+		prepare_rx_descriptor(&RxDescList[i].descr);
+	}
+
+	RxDescList[NBR_OF_RX_DESC - 1].descr.ctrl   = d_eol;
+	RxDescList[NBR_OF_RX_DESC - 1].descr.next   = virt_to_phys(&RxDescList[0]);
+	rx_queue_len = 0;
+
+	/* Initialize transmit descriptors */
+	for (i = 0; i < NBR_OF_TX_DESC; i++) {
+		TxDescList[i].descr.ctrl   = 0;
+		TxDescList[i].descr.sw_len = 0;
+		TxDescList[i].descr.next   = virt_to_phys(&TxDescList[i + 1].descr);
+		TxDescList[i].descr.buf    = 0;
+		TxDescList[i].descr.status = 0;
+		TxDescList[i].descr.hw_len = 0;
+		TxDescList[i].skb = 0;
+	}
 
+	TxDescList[NBR_OF_TX_DESC - 1].descr.ctrl   = d_eol;
+	TxDescList[NBR_OF_TX_DESC - 1].descr.next   = virt_to_phys(&TxDescList[0].descr);
+        
 	/* Initialise initial pointers */
 
-	myNextRxDesc = &RxDescList[0];
-	myLastRxDesc = &RxDescList[NBR_OF_RX_DESC - 1];
-	myPrevRxDesc = &RxDescList[NBR_OF_RX_DESC - 1];
+	myNextRxDesc  = &RxDescList[0];
+	myLastRxDesc  = &RxDescList[NBR_OF_RX_DESC - 1];
+	myPrevRxDesc  = &RxDescList[NBR_OF_RX_DESC - 1];
+	myFirstTxDesc = &TxDescList[0];
+	myNextTxDesc  = &TxDescList[0];
+	myLastTxDesc  = &TxDescList[NBR_OF_TX_DESC - 1];
 
 	/* Initialize speed indicator stuff. */
 
@@ -530,14 +596,14 @@
 		IO_STATE(R_NETWORK_GEN_CONFIG, phy,    mii_clk) |
 		IO_STATE(R_NETWORK_GEN_CONFIG, enable, on);
 
-        *R_NETWORK_TR_CTRL = 
-                IO_STATE(R_NETWORK_TR_CTRL, clr_error, clr) |
-                IO_STATE(R_NETWORK_TR_CTRL, delay, none) |
-                IO_STATE(R_NETWORK_TR_CTRL, cancel, dont) |
-                IO_STATE(R_NETWORK_TR_CTRL, cd, enable) |
-                IO_STATE(R_NETWORK_TR_CTRL, retry, enable) |
-                IO_STATE(R_NETWORK_TR_CTRL, pad, enable) |
-                IO_STATE(R_NETWORK_TR_CTRL, crc, enable);
+	*R_NETWORK_TR_CTRL = 
+		IO_STATE(R_NETWORK_TR_CTRL, clr_error, clr) |
+		IO_STATE(R_NETWORK_TR_CTRL, delay, none) |
+		IO_STATE(R_NETWORK_TR_CTRL, cancel, dont) |
+		IO_STATE(R_NETWORK_TR_CTRL, cd, enable) |
+		IO_STATE(R_NETWORK_TR_CTRL, retry, enable) |
+		IO_STATE(R_NETWORK_TR_CTRL, pad, enable) |
+		IO_STATE(R_NETWORK_TR_CTRL, crc, enable);
 
 	save_flags(flags);
 	cli();
@@ -545,16 +611,13 @@
 	/* enable the irq's for ethernet DMA */
 
 	*R_IRQ_MASK2_SET =
-		IO_STATE(R_IRQ_MASK2_SET, dma0_eop, set) |
-		IO_STATE(R_IRQ_MASK2_SET, dma1_eop, set);
+		IO_STATE(R_IRQ_MASK2_SET, dma1_eop, set); 
 
 	*R_IRQ_MASK0_SET =
 		IO_STATE(R_IRQ_MASK0_SET, overrun,       set) |
 		IO_STATE(R_IRQ_MASK0_SET, underrun,      set) |
 		IO_STATE(R_IRQ_MASK0_SET, excessive_col, set);
 
-	tx_skb = 0;
-
 	/* make sure the irqs are cleared */
 
 	*R_DMA_CH0_CLR_INTR = IO_STATE(R_DMA_CH0_CLR_INTR, clr_eop, do);
@@ -570,6 +633,11 @@
 	*R_DMA_CH1_FIRST = virt_to_phys(myNextRxDesc);
 	*R_DMA_CH1_CMD = IO_STATE(R_DMA_CH1_CMD, cmd, start);
 
+	/* Set up transmit DMA channel so it can be restarted later */
+        
+	*R_DMA_CH0_FIRST = 0;
+	*R_DMA_CH0_DESCR = virt_to_phys(myLastTxDesc);
+
 	restore_flags(flags);
 	
 	/* We are now ready to accept transmit requeusts from
@@ -839,11 +907,18 @@
 	
 	e100_reset_tranceiver();
 	
-	/* and get rid of the packet that never got an interrupt */
-	
-	dev_kfree_skb(tx_skb);
-	tx_skb = 0;
-	
+	/* and get rid of the packets that never got an interrupt */
+	while (myFirstTxDesc != myNextTxDesc)
+	{
+		dev_kfree_skb(myFirstTxDesc->skb);
+		myFirstTxDesc->skb = 0;
+		myFirstTxDesc = phys_to_virt(myFirstTxDesc->descr.next);
+	}
+
+	/* Set up transmit DMA channel so it can be restarted later */
+	*R_DMA_CH0_FIRST = 0;
+	*R_DMA_CH0_DESCR = virt_to_phys(myLastTxDesc);	
+
 	/* tell the upper layers we're ok again */
 	
 	netif_wake_queue(dev);
@@ -866,19 +941,38 @@
 #ifdef ETHDEBUG
 	printk("send packet len %d\n", length);
 #endif
-	spin_lock_irq(&np->lock);  /* protect from tx_interrupt */
+	spin_lock_irq(&np->lock);  /* protect from tx_interrupt and ourself */
+
+	myNextTxDesc->skb = skb;
 
-	tx_skb = skb; /* remember it so we can free it in the tx irq handler later */
 	dev->trans_start = jiffies;
 	
 	e100_hardware_send_packet(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.
-	 */
+	myNextTxDesc = phys_to_virt(myNextTxDesc->descr.next);
 
-	netif_stop_queue(dev);
+	/* Stop queue if full */
+	if (myNextTxDesc == myFirstTxDesc) {
+		/* Enable transmit interrupt to wake up queue */
+		*R_DMA_CH0_CLR_INTR = IO_STATE(R_DMA_CH0_CLR_INTR, clr_eop, do);		
+		*R_IRQ_MASK2_SET = IO_STATE(R_IRQ_MASK2_SET, dma0_eop, set);
+		netif_stop_queue(dev);
+	}
+	else {
+	  /* Report any packets that have been sent */
+		while (myFirstTxDesc != phys_to_virt(*R_DMA_CH0_FIRST) &&
+		       myFirstTxDesc != myNextTxDesc)
+		{
+			np->stats.tx_bytes += myFirstTxDesc->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(myFirstTxDesc->skb);
+			myFirstTxDesc->skb = 0;
+			myFirstTxDesc = phys_to_virt(myFirstTxDesc->descr.next);				
+		}
+	}
 
 	spin_unlock_irq(&np->lock);
 
@@ -936,31 +1030,28 @@
 	struct net_local *np = (struct net_local *)dev->priv;
 
 	/* check for a dma0_eop interrupt */
-	if (irqbits & IO_STATE(R_IRQ_MASK2_RD, dma0_eop, 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_CH0_CLR_INTR = IO_STATE(R_DMA_CH0_CLR_INTR, clr_eop, do);
+	if (irqbits & IO_STATE(R_IRQ_MASK2_RD, dma0_eop, active)) {
+		/* Report all sent packets */
+		do {
+			/* acknowledge the eop interrupt */
+			*R_DMA_CH0_CLR_INTR = IO_STATE(R_DMA_CH0_CLR_INTR, clr_eop, do);
 
-		if (*R_DMA_CH0_FIRST == 0 && tx_skb) {
-			np->stats.tx_bytes += tx_skb->len;
+			np->stats.tx_bytes += myFirstTxDesc->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);
-		}
+			dev_kfree_skb_irq(myFirstTxDesc->skb);
+			myFirstTxDesc->skb = 0;
 
-		spin_unlock(&np->lock);
+			if (netif_queue_stopped(dev)) {
+			  	/* Queue is running, disable tx IRQ */
+			  	*R_IRQ_MASK2_CLR = IO_STATE(R_IRQ_MASK2_CLR, dma0_eop, clr);		
+				netif_wake_queue(dev);
+			}
+			myFirstTxDesc = phys_to_virt(myFirstTxDesc->descr.next);
+		} while (myFirstTxDesc != phys_to_virt(*R_DMA_CH0_FIRST) &&
+		         myFirstTxDesc != myNextTxDesc);
 	}
 }
 
@@ -989,7 +1080,6 @@
 		np->stats.tx_errors++;
 		D(printk("ethernet excessive collisions!\n"));
 	}
-
 }
 
 /* We have a good packet(s), get it/them out of the buffers. */
@@ -999,13 +1089,12 @@
 	struct sk_buff *skb;
 	int length = 0;
 	struct net_local *np = (struct net_local *)dev->priv;
-	struct etrax_dma_descr *mySaveRxDesc = myNextRxDesc;
 	unsigned char *skb_data_ptr;
 #ifdef ETHDEBUG
 	int i;
 #endif
 
-	if (!led_active && jiffies > led_next_time) {
+	if (!led_active && time_after(jiffies, led_next_time)) {
 		/* light the network leds depending on the current speed. */
 		e100_set_network_leds(NETWORK_ACTIVITY);
 
@@ -1015,24 +1104,13 @@
 		mod_timer(&clear_led_timer, jiffies + HZ/10);
 	}
 
-	/* 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 */
+	length = myNextRxDesc->descr.hw_len - 4;
 	((struct net_local *)dev->priv)->stats.rx_bytes += length;
 
 #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);
+	skb_data_ptr = (unsigned char *)phys_to_virt(myNextRxDesc->descr.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],
@@ -1041,53 +1119,55 @@
 	}
 #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;
-	}
+	if (length < RX_COPYBREAK) {
+		/* Small packet, copy data */
+		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 */
+		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);
+		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(myNextRxDesc->descr.buf), length);
+	}
+	else {
+		/* Large packet, send directly to upper layers and allocate new memory */		 
+		skb = myNextRxDesc->skb;
+		skb_put(skb, length);
+		myNextRxDesc->skb = dev_alloc_skb(MAX_MEDIA_DATA_SIZE);
+		myNextRxDesc->descr.buf = virt_to_phys(myNextRxDesc->skb->data);
 	}
-
-	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;
+	myNextRxDesc->descr.status = 0;
 	myPrevRxDesc = myNextRxDesc;
-	myNextRxDesc = phys_to_virt(myNextRxDesc->next);
+	myNextRxDesc = phys_to_virt(myNextRxDesc->descr.next);
 
-	myPrevRxDesc->ctrl |= d_eol;
-	myLastRxDesc->ctrl &= ~d_eol;
-	myLastRxDesc = myPrevRxDesc;
+	rx_queue_len++;
 
-	return;
+	/* Check if descriptors should be returned */
+	if (rx_queue_len == RX_QUEUE_THRESHOLD) {
+		flush_etrax_cache();
+		myPrevRxDesc->descr.ctrl |= d_eol;
+		myLastRxDesc->descr.ctrl &= ~d_eol;
+		myLastRxDesc = myPrevRxDesc;
+		rx_queue_len = 0;
+	}
 }
 
 /* The inverse routine to net_open(). */
@@ -1297,7 +1377,7 @@
 {
 	D(printk("e100 send pack, buf 0x%x len %d\n", buf, length));
 
-	if (!led_active && jiffies > led_next_time) {
+	if (!led_active && time_after(jiffies, led_next_time)) {
 		/* light the network leds depending on the current speed. */
 		e100_set_network_leds(NETWORK_ACTIVITY);
 
@@ -1308,21 +1388,22 @@
 	}
 
 	/* configure the tx dma descriptor */
+	myNextTxDesc->descr.sw_len = length;
+	myNextTxDesc->descr.ctrl = d_eop | d_eol | d_wait;
+	myNextTxDesc->descr.buf = virt_to_phys(buf);
+
+        /* Move end of list */
+        myLastTxDesc->descr.ctrl &= ~d_eol;
+        myLastTxDesc = myNextTxDesc;
 
-	TxDesc.sw_len = length;
-	TxDesc.ctrl = d_eop | d_eol | d_wait;
-	TxDesc.buf = virt_to_phys(buf);
-
-	/* setup the dma channel and start it */
-
-	*R_DMA_CH0_FIRST = virt_to_phys(&TxDesc);
-	*R_DMA_CH0_CMD = IO_STATE(R_DMA_CH0_CMD, cmd, start);
+	/* Restart DMA channel */
+	*R_DMA_CH0_CMD = IO_STATE(R_DMA_CH0_CMD, cmd, restart);
 }
 
 static void
 e100_clear_network_leds(unsigned long dummy)
 {
-	if (led_active && jiffies > led_next_time) {
+	if (led_active && time_after(jiffies, led_next_time)) {
 		e100_set_network_leds(NO_NETWORK_ACTIVITY);
 
 		/* Set the earliest time we may set the LED */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/cris/drivers/gpio.c linux/arch/cris/drivers/gpio.c
--- linux.orig/arch/cris/drivers/gpio.c	Mon Feb 25 19:37:52 2002
+++ linux/arch/cris/drivers/gpio.c	Tue May 28 22:39:12 2002
@@ -1,14 +1,26 @@
-/* $Id: gpio.c,v 1.12 2001/11/12 19:42:15 pkj Exp $
+/* $Id: gpio.c,v 1.15 2002/05/06 13:19:13 johana Exp $
  *
  * Etrax general port I/O device
  *
- * Copyright (c) 1999, 2000, 2001 Axis Communications AB
+ * Copyright (c) 1999, 2000, 2001, 2002 Axis Communications AB
  *
  * Authors:    Bjorn Wesen      (initial version)
  *             Ola Knutsson     (LED handling)
- *             Johan Adolfsson  (read/set directions, write)
+ *             Johan Adolfsson  (read/set directions, write, port G)
  *
  * $Log: gpio.c,v $
+ * Revision 1.15  2002/05/06 13:19:13  johana
+ * IO_SETINPUT returns mask with bit set = inputs for PA and PB as well.
+ *
+ * Revision 1.14  2002/04/12 12:01:53  johana
+ * Use global r_port_g_data_shadow.
+ * Moved gpio_init_port_g() closer to gpio_init() and marked it __init.
+ *
+ * Revision 1.13  2002/04/10 12:03:55  johana
+ * Added support for port G /dev/gpiog (minor 3).
+ * Changed indentation on switch cases.
+ * Fixed other spaces to tabs.
+ *
  * Revision 1.12  2001/11/12 19:42:15  pkj
  * * Corrected return values from gpio_leds_ioctl().
  * * Fixed compiler warnings.
@@ -94,14 +106,17 @@
 
 struct gpio_private {
 	struct gpio_private *next;
+	/* These fields are for PA and PB only */
 	volatile unsigned char *port, *shadow;
 	volatile unsigned char *dir, *dir_shadow;
 	unsigned char changeable_dir;
 	unsigned char changeable_bits;
-	unsigned char highalarm, lowalarm;
 	unsigned char clk_mask;
 	unsigned char data_mask;
 	unsigned char write_msb;
+	unsigned char pad1, pad2, pad3;
+	/* These fields are generic */
+	unsigned long highalarm, lowalarm;
 	wait_queue_head_t alarm_wq;
 	int minor;
 };
@@ -110,10 +125,17 @@
 
 static struct gpio_private *alarmlist = 0;
 
-#define NUM_PORTS 2
-static volatile unsigned char *ports[2] = { R_PORT_PA_DATA, R_PORT_PB_DATA };
-static volatile unsigned char *shads[2] = {
-	&port_pa_data_shadow, &port_pb_data_shadow };
+/* Port A and B use 8 bit access, but Port G is 32 bit */
+#define NUM_PORTS (GPIO_MINOR_B+1)
+
+static volatile unsigned char *ports[NUM_PORTS] = { 
+	R_PORT_PA_DATA, 
+	R_PORT_PB_DATA,
+};
+static volatile unsigned char *shads[NUM_PORTS] = {
+	&port_pa_data_shadow, 
+	&port_pb_data_shadow
+};
 
 /* What direction bits that are user changeable 1=changeable*/
 #ifndef CONFIG_ETRAX_PA_CHANGEABLE_DIR
@@ -131,17 +153,36 @@
 #endif
 
 
-static unsigned char changeable_dir[2] = { CONFIG_ETRAX_PA_CHANGEABLE_DIR,
-                                           CONFIG_ETRAX_PB_CHANGEABLE_DIR };
-static unsigned char changeable_bits[2] = { CONFIG_ETRAX_PA_CHANGEABLE_BITS,
-                                            CONFIG_ETRAX_PB_CHANGEABLE_BITS };
+static unsigned char changeable_dir[NUM_PORTS] = { 
+	CONFIG_ETRAX_PA_CHANGEABLE_DIR,
+	CONFIG_ETRAX_PB_CHANGEABLE_DIR 
+};
+static unsigned char changeable_bits[NUM_PORTS] = { 
+	CONFIG_ETRAX_PA_CHANGEABLE_BITS,
+	CONFIG_ETRAX_PB_CHANGEABLE_BITS 
+};
 
-static volatile unsigned char *dir[2] = { R_PORT_PA_DIR, R_PORT_PB_DIR };
+static volatile unsigned char *dir[NUM_PORTS] = { 
+	R_PORT_PA_DIR, 
+	R_PORT_PB_DIR 
+};
+
+static volatile unsigned char *dir_shadow[NUM_PORTS] = {
+	&port_pa_dir_shadow, 
+	&port_pb_dir_shadow 
+};
+
+/* Port G is 32 bit, handle it special, some bits are both inputs 
+   and outputs at the same time, only some of the bits can change direction
+   and some of them in groups of 8 bit. */
+static unsigned long changeable_dir_g;
+static unsigned long dir_g_in_bits;
+static unsigned long dir_g_out_bits;
+static unsigned long dir_g_shadow; /* 1=output */
+
+#define USE_PORTS(priv) ((priv)->minor <= GPIO_MINOR_B)
 
-static volatile unsigned char *dir_shadow[2] = {
-	&port_pa_dir_shadow, &port_pb_dir_shadow };
 
-#define LEDS 2
 
 static unsigned int 
 gpio_poll(struct file *filp,
@@ -149,10 +190,10 @@
 {
 	/* TODO poll on alarms! */
 #if 0
-        if (!ANYTHING_WANTED) {
+	if (!ANYTHING_WANTED) {
 		D(printk("gpio_select sleeping task\n"));
-	        select_wait(&gpio_wq, table);
-	        return 0;
+		select_wait(&gpio_wq, table);
+		return 0;
 	}
 	D(printk("gpio_select ready\n"));
 #endif
@@ -166,6 +207,10 @@
 	unsigned char data, clk_mask, data_mask, write_msb;
 	unsigned long flags;
 	ssize_t retval = count;
+	if (priv->minor !=GPIO_MINOR_A && priv->minor != GPIO_MINOR_B) {
+		return -EFAULT;
+	}
+    
 	if (verify_area(VERIFY_READ, buf, count)) {
 		return -EFAULT;
 	}
@@ -210,13 +255,15 @@
 	return retval;
 }
 
+
+
 static int
 gpio_open(struct inode *inode, struct file *filp)
 {
 	struct gpio_private *priv;
 	int p = MINOR(inode->i_rdev);
 
-	if (p >= NUM_PORTS && p != LEDS)
+	if (p > GPIO_MINOR_LAST)
 		return -EINVAL;
 
 	priv = (struct gpio_private *)kmalloc(sizeof(struct gpio_private), 
@@ -231,13 +278,21 @@
 
 	priv->next = alarmlist;
 	alarmlist = priv;
-	priv->port = ports[p];
-	priv->shadow = shads[p];
-
-	priv->changeable_dir = changeable_dir[p];
-	priv->changeable_bits = changeable_bits[p];
-	priv->dir = dir[p];
-	priv->dir_shadow = dir_shadow[p];
+	if (USE_PORTS(priv)) { /* A and B */
+		priv->port = ports[p];
+		priv->shadow = shads[p];
+		priv->dir = dir[p];
+		priv->dir_shadow = dir_shadow[p];
+		priv->changeable_dir = changeable_dir[p];
+		priv->changeable_bits = changeable_bits[p];
+	} else {
+		priv->port = NULL;
+		priv->shadow = NULL;
+		priv->dir = NULL;
+		priv->dir_shadow = NULL;
+		priv->changeable_dir = 0;
+		priv->changeable_bits = 0;
+	}
 
 	priv->highalarm = 0;
 	priv->lowalarm = 0;
@@ -289,87 +344,189 @@
 	}
 
 	switch (_IOC_NR(cmd)) {
-		case IO_READBITS:
-			// read the port
+	case IO_READBITS:
+		// read the port
+		if (USE_PORTS(priv)) {
 			return *priv->port;
-		case IO_SETBITS:
-			save_flags(flags); cli();
-			// set changeable bits with a 1 in arg
+		} else if (priv->minor == GPIO_MINOR_G) {
+			return *R_PORT_G_DATA;
+		}
+		break;
+	case IO_SETBITS:
+		save_flags(flags); cli();
+		// set changeable bits with a 1 in arg
+		if (USE_PORTS(priv)) {
 			*priv->port = *priv->shadow |= 
 			  ((unsigned char)arg & priv->changeable_bits);
-			restore_flags(flags);
-			break;
-		case IO_CLRBITS:
-			save_flags(flags); cli();
-			// clear changeable bits with a 1 in arg
+		} else if (priv->minor == GPIO_MINOR_G) {
+			*R_PORT_G_DATA = port_g_data_shadow |= (arg & dir_g_out_bits);
+		}
+		restore_flags(flags);
+		break;
+	case IO_CLRBITS:
+		save_flags(flags); cli();
+		// clear changeable bits with a 1 in arg
+		if (USE_PORTS(priv)) {
 			*priv->port = *priv->shadow &= 
-			  ~((unsigned char)arg & priv->changeable_bits);
-			restore_flags(flags);
-			break;
-		case IO_HIGHALARM:
-			// set alarm when bits with 1 in arg go high
-			priv->highalarm |= (unsigned char)arg;
-			break;
-		case IO_LOWALARM:
-			// set alarm when bits with 1 in arg go low
-			priv->lowalarm |= (unsigned char)arg;
-			break;
-		case IO_CLRALARM:
-			// clear alarm for bits with 1 in arg
-			priv->highalarm &= ~(unsigned char)arg;
-			priv->lowalarm  &= ~(unsigned char)arg;
-			break;
-		case IO_READDIR:
-			/* Read direction 0=input 1=output */
+			 ~((unsigned char)arg & priv->changeable_bits);
+		} else if (priv->minor == GPIO_MINOR_G) {
+			*R_PORT_G_DATA = port_g_data_shadow &= ~((unsigned long)arg & dir_g_out_bits);
+		}
+		restore_flags(flags);
+		break;
+	case IO_HIGHALARM:
+		// set alarm when bits with 1 in arg go high
+		priv->highalarm |= arg;
+		break;
+	case IO_LOWALARM:
+		// set alarm when bits with 1 in arg go low
+		priv->lowalarm |= arg;
+		break;
+	case IO_CLRALARM:
+		// clear alarm for bits with 1 in arg
+		priv->highalarm &= ~arg;
+		priv->lowalarm  &= ~arg;
+		break;
+	case IO_READDIR:
+		/* Read direction 0=input 1=output */
+		if (USE_PORTS(priv)) {
 			return *priv->dir_shadow;
-		case IO_SETINPUT:
+		} else if (priv->minor == GPIO_MINOR_G) {
+			/* Note: Some bits are both in and out,
+			 * Those that are dual is set hare as well.
+			 */
+			return dir_g_shadow | dir_g_out_bits;
+		}
+	case IO_SETINPUT:
+		/* Set direction 0=unchanged 1=input, 
+		 * return mask with 1=input 
+		 */
+		if (USE_PORTS(priv)) {
 			save_flags(flags); cli();
-			/* Set direction 0=unchanged 1=input */
 			*priv->dir = *priv->dir_shadow &= 
 			~((unsigned char)arg & priv->changeable_dir);
 			restore_flags(flags);
-			return *priv->dir_shadow;
-		case IO_SETOUTPUT:
+			return ~(*priv->dir_shadow);
+		} else if (priv->minor == GPIO_MINOR_G) {
+			/* We must fiddle with R_GEN_CONFIG to change dir */
+			if (((arg & dir_g_in_bits) != arg) && 
+			    (arg & changeable_dir_g)) {
+				arg &= changeable_dir_g;
+				/* Clear bits in genconfig to set to input */
+				if (arg & (1<<0)) {
+					genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g0dir);
+					dir_g_in_bits |= (1<<0);
+					dir_g_out_bits &= ~(1<<0);
+				}
+				if ((arg & 0x0000FF00) == 0x0000FF00) {
+					genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g8_15dir);
+					dir_g_in_bits |= 0x0000FF00;
+					dir_g_out_bits &= ~0x0000FF00;
+				}
+				if ((arg & 0x00FF0000) == 0x00FF0000) {
+					genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g16_23dir);
+					dir_g_in_bits |= 0x00FF0000;
+					dir_g_out_bits &= ~0x00FF0000;
+				}
+				if (arg & (1<<24)) {
+					genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g24dir);
+					dir_g_in_bits |= (1<<24);
+					dir_g_out_bits &= ~(1<<24);
+				}
+				printk("gpio: SETINPUT on port G set "
+					"genconfig to 0x%08lX "
+					"in_bits: 0x%08lX "
+					"out_bits: 0x%08lX\n", 
+				       (unsigned long)genconfig_shadow, 
+				       dir_g_in_bits, dir_g_out_bits);
+				*R_GEN_CONFIG = genconfig_shadow;
+				/* Must be a >120 ns delay before writing this again */
+				
+			}
+			return dir_g_in_bits;
+		}
+		return 0;
+
+	case IO_SETOUTPUT:
+		/* Set direction 0=unchanged 1=output, 
+		 * return mask with 1=output 
+		 */
+		if (USE_PORTS(priv)) {
 			save_flags(flags); cli();
-			/* Set direction 0=unchanged 1=output */
 			*priv->dir = *priv->dir_shadow |= 
 			  ((unsigned char)arg & priv->changeable_dir);
 			restore_flags(flags);
 			return *priv->dir_shadow;
-                case IO_SHUTDOWN:
-                       SOFT_SHUTDOWN();
-                       break;
-                case IO_GET_PWR_BT:
+		} else if (priv->minor == GPIO_MINOR_G) {
+			/* We must fiddle with R_GEN_CONFIG to change dir */			
+			if (((arg & dir_g_out_bits) != arg) &&
+			    (arg & changeable_dir_g)) {
+				/* Set bits in genconfig to set to output */
+				if (arg & (1<<0)) {
+					genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g0dir);
+					dir_g_out_bits |= (1<<0);
+					dir_g_in_bits &= ~(1<<0);
+				}
+				if ((arg & 0x0000FF00) == 0x0000FF00) {
+					genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g8_15dir);
+					dir_g_out_bits |= 0x0000FF00;
+					dir_g_in_bits &= ~0x0000FF00;
+				}
+				if ((arg & 0x00FF0000) == 0x00FF0000) {
+					genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g16_23dir);
+					dir_g_out_bits |= 0x00FF0000;
+					dir_g_in_bits &= ~0x00FF0000;
+				}
+				if (arg & (1<<24)) {
+					genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g24dir);
+					dir_g_out_bits |= (1<<24);
+					dir_g_in_bits &= ~(1<<24);
+				}
+				printk("gpio: SETOUTPUT on port G set "
+					"genconfig to 0x%08lX "
+					"in_bits: 0x%08lX "
+					"out_bits: 0x%08lX\n", 
+				       (unsigned long)genconfig_shadow, 
+				       dir_g_in_bits, dir_g_out_bits);
+				*R_GEN_CONFIG = genconfig_shadow;
+				/* Must be a >120 ns delay before writing this again */
+			}
+			return dir_g_out_bits;
+		}
+		return 0;
+	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));
+		return (*R_PORT_G_DATA & ( 1 << CONFIG_ETRAX_POWERBUTTON_BIT));
 #else
-                       return 0;
+		return 0;
 #endif
-			break;
-		case IO_CFG_WRITE_MODE:
-			priv->clk_mask = arg & 0xFF;
-			priv->data_mask = (arg >> 8) & 0xFF;
-			priv->write_msb = (arg >> 16) & 0x01;
-			/* Check if we're allowed to change the bits and
-			 * the direction is correct
-			 */
-			if (!((priv->clk_mask & priv->changeable_bits) &&
-			      (priv->data_mask & priv->changeable_bits) &&
-			      (priv->clk_mask & *priv->dir_shadow) &&
-			      (priv->data_mask & *priv->dir_shadow)))
-			{
-				priv->clk_mask = 0;
-				priv->data_mask = 0;
-				return -EPERM;
-			}
-			break;
-		default:
-			if (priv->minor == LEDS)
-				return gpio_leds_ioctl(cmd, arg);
-                        else
-				return -EINVAL;
-	}
+		break;
+	case IO_CFG_WRITE_MODE:
+		priv->clk_mask = arg & 0xFF;
+		priv->data_mask = (arg >> 8) & 0xFF;
+		priv->write_msb = (arg >> 16) & 0x01;
+		/* Check if we're allowed to change the bits and
+		 * the direction is correct
+		 */
+		if (!((priv->clk_mask & priv->changeable_bits) &&
+		      (priv->data_mask & priv->changeable_bits) &&
+		      (priv->clk_mask & *priv->dir_shadow) &&
+		      (priv->data_mask & *priv->dir_shadow)))
+		{
+			priv->clk_mask = 0;
+			priv->data_mask = 0;
+			return -EPERM;
+		}
+		break;
+	default:
+		if (priv->minor == GPIO_MINOR_LEDS)
+			return gpio_leds_ioctl(cmd, arg);
+		else
+			return -EINVAL;
+	} /* switch */
 	
 	return 0;
 }
@@ -381,24 +538,24 @@
 	unsigned char red;
 
 	switch (_IOC_NR(cmd)) {
-		case IO_LEDACTIVE_SET:
-			green = ((unsigned char) arg) & 1;
-			red   = (((unsigned char) arg) >> 1) & 1;
-			LED_ACTIVE_SET_G(green);
-			LED_ACTIVE_SET_R(red);
-			break;
-
-		case IO_LED_SETBIT:                 
-			LED_BIT_SET(arg);
-			break;
-
-		case IO_LED_CLRBIT:
-			LED_BIT_CLR(arg);
-			break;
+	case IO_LEDACTIVE_SET:
+		green = ((unsigned char) arg) & 1;
+		red   = (((unsigned char) arg) >> 1) & 1;
+		LED_ACTIVE_SET_G(green);
+		LED_ACTIVE_SET_R(red);
+		break;
+
+	case IO_LED_SETBIT:
+		LED_BIT_SET(arg);
+		break;
+
+	case IO_LED_CLRBIT:
+		LED_BIT_CLR(arg);
+		break;
 
-		default:
-			return -EINVAL;
-	}
+	default:
+		return -EINVAL;
+	} /* switch */
 
 	return 0;
 }
@@ -412,6 +569,92 @@
 	release:     gpio_release,
 };
 
+
+static void __init gpio_init_port_g(void)
+{
+#define GROUPA (0x0000FF3F)
+#define GROUPB (1<<6 | 1<<7)
+#define GROUPC (1<<30 | 1<<31)
+#define GROUPD (0x3FFF0000)
+#define GROUPD_LOW (0x00FF0000)
+	unsigned long used_in_bits = 0;
+	unsigned long used_out_bits = 0;
+	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, scsi0, select)){
+		used_in_bits  |= GROUPA | GROUPB | 0 | 0;
+		used_out_bits |= GROUPA | GROUPB | 0 | 0;
+	}
+	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, ata, select)) {
+		used_in_bits  |= GROUPA | GROUPB | GROUPC | (GROUPD & ~(1<<25|1<<26));
+		used_out_bits |= GROUPA | GROUPB | GROUPC | GROUPD;
+	}
+
+	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, par0, select)) {
+		used_in_bits  |= (GROUPA & ~(1<<0)) | 0 | 0 | 0;
+		used_out_bits |= (GROUPA & ~(1<<0)) | 0 | 0 | 0;
+	}
+	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, ser2, select)) {
+		used_in_bits  |= 0 | GROUPB | 0 | 0;
+		used_out_bits |= 0 | GROUPB | 0 | 0;
+	}
+	/* mio same as shared RAM ? */
+	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, mio, select)) {
+		used_in_bits  |= (GROUPA & ~(1<<0)) | 0 |0 |GROUPD_LOW;
+		used_out_bits |= (GROUPA & ~(1<<0|1<<1|1<<2)) | 0 |0 |GROUPD_LOW;
+	}
+	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, scsi1, select)) {
+		used_in_bits  |= 0 | 0 | GROUPC | GROUPD;
+		used_out_bits |= 0 | 0 | GROUPC | GROUPD;
+	}
+	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, scsi0w, select)) {
+		used_in_bits  |= GROUPA | GROUPB | 0 | (GROUPD_LOW | 1<<24);
+		used_out_bits |= GROUPA | GROUPB | 0 | (GROUPD_LOW | 1<<24 | 1<<25|1<<26);
+	}
+
+	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, par1, select)) {
+		used_in_bits  |= 0 | 0 | 0 | (GROUPD & ~(1<<24));
+		used_out_bits |= 0 | 0 | 0 | (GROUPD & ~(1<<24));
+	}
+	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, ser3, select)) {
+		used_in_bits  |= 0 | 0 | GROUPC | 0;
+		used_out_bits |= 0 | 0 | GROUPC | 0;
+	}
+	/* mio same as shared RAM-W? */
+	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, mio_w, select)) {
+		used_in_bits  |= (GROUPA & ~(1<<0)) | 0 | 0 |GROUPD_LOW;
+		used_out_bits |= (GROUPA & ~(1<<0|1<<1|1<<2)) | 0 | 0 |GROUPD_LOW;
+	}
+	/* TODO: USB p2, parw, sync ser3? */
+
+	/* Initialise the dir_g_shadow etc. depending on genconfig */
+	/* 0=input 1=output */
+	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g0dir, out)) 
+		dir_g_shadow |= (1 << 0);
+	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g8_15dir, out))
+		dir_g_shadow |= 0x0000FF00;
+	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g16_23dir, out))
+		dir_g_shadow |= 0x00FF0000;
+	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g24dir, out))
+		dir_g_shadow |= (1 << 24);
+
+	dir_g_in_bits = ~used_in_bits;
+	dir_g_out_bits = ~used_out_bits;
+
+	changeable_dir_g = 0x01FFFF01; /* all that can change dir */
+	changeable_dir_g &= dir_g_out_bits;
+	changeable_dir_g &= dir_g_in_bits;
+	/* Correct the bits that can change direction */ 
+	dir_g_out_bits &= ~changeable_dir_g;
+	dir_g_out_bits |= dir_g_shadow;
+	dir_g_in_bits &= ~changeable_dir_g;
+	dir_g_in_bits |= (~dir_g_shadow & changeable_dir_g);
+
+
+	printk("GPIO port G: in_bits: 0x%08lX out_bits: 0x%08lX val: %08lX\n",
+	       dir_g_in_bits, dir_g_out_bits, (unsigned long)*R_PORT_G_DATA);
+	printk("GPIO port G: dir: %08lX changeable: %08lX\n", 
+	       dir_g_shadow, changeable_dir_g);
+}
+
 /* main driver initialization routine, called from mem.c */
 
 static __init int
@@ -431,13 +674,13 @@
 		return res;
 	}
 
-        /* Clear all leds */
+	/* 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);        
+	LED_DISK_WRITE(0);
 
 #if defined (CONFIG_ETRAX_CSP0_LEDS)
 	for (i = 0; i < 32; i++) {
@@ -446,8 +689,8 @@
 #endif
 
 #endif
-	
-	printk("ETRAX 100LX GPIO driver v2.2, (c) 2001 Axis Communications AB\n");
+	gpio_init_port_g();
+	printk("ETRAX 100LX GPIO driver v2.3, (c) 2001, 2002 Axis Communications AB\n");
 
 	return res;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/cris/drivers/ide.c linux/arch/cris/drivers/ide.c
--- linux.orig/arch/cris/drivers/ide.c	Wed Jul  4 18:50:38 2001
+++ linux/arch/cris/drivers/ide.c	Tue May 28 22:39:19 2002
@@ -1,13 +1,34 @@
-/* $Id: ide.c,v 1.19 2001/05/09 12:53:16 johana Exp $
+/* $Id: ide.c,v 1.24 2002/04/22 11:47:21 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.
- * Copyright (c) 2000, 2001 Axis Communications AB 
+ * Copyright (c) 2000, 2001, 2002 Axis Communications AB 
  *
  * Authors:    Bjorn Wesen        (initial version)
  *             Mikael Starvik     (pio setup stuff)
  *
  * $Log: ide.c,v $
+ * Revision 1.24  2002/04/22 11:47:21  johana
+ * Fix according to 2.4.19-pre7. time_after/time_before and
+ * missing end of comment.
+ * The patch has a typo for ethernet.c in e100_clear_network_leds(),
+ *  that is fixed here.
+ *
+ * Revision 1.23  2002/03/19 15:35:51  bjornw
+ * Cleaned up the bus-reset code a bit and made G27-reset work
+ *
+ * Revision 1.22  2002/03/19 15:23:05  bjornw
+ * Added flush_etrax_cache before starting the receiving DMA
+ *
+ * Revision 1.21  2002/03/06 15:37:56  hp
+ * 	* ide.c (OUT_BYTE): If timing out in the first busy-loop, do a
+ * 	printk, fall through and still do the write.
+ * 	(IN_BYTE): If timing out in the first loop, and reg indicated it's
+ * 	the ATA status register in the device being read, return BUSY_STAT.
+ *
+ * Revision 1.20  2002/02/22 11:47:56  bjornw
+ * Added a timeout to IN_BYTE and OUT_BYTE
+ *
  * Revision 1.19  2001/05/09 12:53:16  johana
  * Added #include <asm/dma.h>
  *
@@ -112,6 +133,13 @@
 /* number of Etrax DMA descriptors */
 #define MAX_DMA_DESCRS 64
 
+/* number of times to retry busy-flags when reading/writing IDE-registers 
+ * this can't be too high because a hung harddisk might cause the watchdog
+ * to trigger (sometimes IN_BYTE and OUT_BYTE are called with irq's disabled)
+ */
+
+#define IDE_REGISTER_TIMEOUT 300
+
 #ifdef CONFIG_ETRAX_IDE_CSE1_16_RESET
 /* address where the memory-mapped IDE reset bit lives, if used */
 static volatile unsigned long *reset_addr;
@@ -120,21 +148,84 @@
 #define LOWDB(x)
 #define D(x) 
 
-void OUT_BYTE(unsigned char data, ide_ioreg_t reg) {
+void 
+OUT_BYTE(unsigned char data, ide_ioreg_t reg) {
+	int timeleft;
 	LOWDB(printk("ob: data 0x%x, reg 0x%x\n", data, reg));
-	while(*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy)); /* wait for busy flag */
+
+	/* note the lack of handling any timeouts. we stop waiting, but we don't
+	 * really notify anybody.
+	 */
+
+	timeleft = IDE_REGISTER_TIMEOUT;
+	/* wait for busy flag */
+	while(timeleft && (*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy)))
+		timeleft--;
+
+	/*
+	 * Fall through at a timeout, so the ongoing command will be
+	 * aborted by the write below, which is expected to be a dummy
+	 * command to the command register.  This happens when a faulty
+	 * drive times out on a command.  See comment on timeout in
+	 * IN_BYTE.
+	 */
+	if(!timeleft)
+		printk("ATA timeout reg 0x%lx := 0x%x\n", reg, data);
+
 	*R_ATA_CTRL_DATA = reg | data; /* write data to the drive's register */
-	while(!(*R_ATA_STATUS_DATA &
-		IO_MASK(R_ATA_STATUS_DATA, tr_rdy))); /* wait for transmitter ready */
+
+	timeleft = IDE_REGISTER_TIMEOUT;
+	/* wait for transmitter ready */
+	while(timeleft && !(*R_ATA_STATUS_DATA &
+			    IO_MASK(R_ATA_STATUS_DATA, tr_rdy)))
+		timeleft--;
 }
 
-unsigned char IN_BYTE(ide_ioreg_t reg) {
+unsigned char 
+IN_BYTE(ide_ioreg_t reg) {
 	int status;
-	while(*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy)); /* wait for busy flag */
+	int timeleft;
+
+	timeleft = IDE_REGISTER_TIMEOUT;
+	/* wait for busy flag */
+	while(timeleft && (*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy)))
+		timeleft--;
+
+	if(!timeleft) {
+		/*
+		 * If we're asked to read the status register, like for
+		 * example when a command does not complete for an
+		 * extended time, but the ATA interface is stuck in a
+		 * busy state at the *ETRAX* ATA interface level (as has
+		 * happened repeatedly with at least one bad disk), then
+		 * the best thing to do is to pretend that we read
+		 * "busy" in the status register, so the IDE driver will
+		 * time-out, abort the ongoing command and perform a
+		 * reset sequence.  Note that the subsequent OUT_BYTE
+		 * call will also timeout on busy, but as long as the
+		 * write is still performed, everything will be fine.
+		 */
+		if ((reg & IO_MASK (R_ATA_CTRL_DATA, addr))
+		    == IO_FIELD (R_ATA_CTRL_DATA, addr, IDE_STATUS_OFFSET))
+			return BUSY_STAT;
+		else
+			/* For other rare cases we assume 0 is good enough.  */
+			return 0;
+	}
+
 	*R_ATA_CTRL_DATA = reg | IO_STATE(R_ATA_CTRL_DATA, rw, read); /* read data */ 
-	while(!((status = *R_ATA_STATUS_DATA) &
-		IO_MASK(R_ATA_STATUS_DATA, dav))); /* wait for available */
+
+	timeleft = IDE_REGISTER_TIMEOUT;
+	/* wait for available */
+	while(timeleft && !((status = *R_ATA_STATUS_DATA) &
+			    IO_MASK(R_ATA_STATUS_DATA, dav)))
+		timeleft--;
+
+	if(!timeleft)
+		return 0;
+
 	LOWDB(printk("inb: 0x%x from reg 0x%x\n", status & 0xff, reg));
+
 	return (unsigned char)status; /* data was in the lower 16 bits in the status reg */
 }
 
@@ -279,20 +370,8 @@
 		hwif->dmaproc = &e100_dmaproc;
 		hwif->ideproc = &e100_ideproc;
 	}
-	/* actually reset and configure the etrax100 ide/ata interface */
 
-	/* This is mystifying; why is not G27 SET anywhere ? It's just reset here twice. */
-
-	/* de-assert bus-reset */
-#ifdef CONFIG_ETRAX_IDE_PB7_RESET  
-	port_pb_dir_shadow = port_pb_dir_shadow | 
-		IO_STATE(R_PORT_PB_DIR, dir7, output);
-	*R_PORT_PB_DIR = port_pb_dir_shadow;
-	REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, 7, 1);
-#endif
-#ifdef CONFIG_ETRAX_IDE_G27_RESET
-	*R_PORT_G_DATA = 0;
-#endif 
+	/* actually reset and configure the etrax100 ide/ata interface */
 
 	*R_ATA_CTRL_DATA = 0;
 	*R_ATA_TRANSFER_CNT = 0;
@@ -308,19 +387,32 @@
 
 	*R_GEN_CONFIG = genconfig_shadow;
 
+        /* pull the chosen /reset-line low */
+        
+#ifdef CONFIG_ETRAX_IDE_G27_RESET
+        REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, 27, 0);
+#endif 
 #ifdef CONFIG_ETRAX_IDE_CSE1_16_RESET
         init_ioremap();
         REG_SHADOW_SET(port_cse1_addr, port_cse1_shadow, 16, 0);
 #endif
-
 #ifdef CONFIG_ETRAX_IDE_CSP0_8_RESET
         init_ioremap();
         REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, 8, 0);
 #endif
+#ifdef CONFIG_ETRAX_IDE_PB7_RESET  
+	port_pb_dir_shadow = port_pb_dir_shadow | 
+		IO_STATE(R_PORT_PB_DIR, dir7, output);
+	*R_PORT_PB_DIR = port_pb_dir_shadow;
+	REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, 7, 1);
+#endif
 
 	/* wait some */
+
 	udelay(25);
 
+	/* de-assert bus-reset */
+
 #ifdef CONFIG_ETRAX_IDE_CSE1_16_RESET
 	REG_SHADOW_SET(port_cse1_addr, port_cse1_shadow, 16, 1);
 #endif
@@ -328,7 +420,7 @@
 	REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, 8, 1);
 #endif
 #ifdef CONFIG_ETRAX_IDE_G27_RESET
-	*R_PORT_G_DATA = 0; /* de-assert bus-reset */
+	REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, 27, 1);
 #endif 
 
 	/* make a dummy read to set the ata controller in a proper state */
@@ -351,12 +443,13 @@
 			     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_ETRAX_IDE_DELAY);
+	printk("ide: waiting %d seconds for drives to regain consciousness\n",
+	       CONFIG_ETRAX_IDE_DELAY);
 
 	h = jiffies + (CONFIG_ETRAX_IDE_DELAY * HZ);
-	while(jiffies < h) ;
+	while(time_before(jiffies, h)) /* nothing */ ;
 
-  /* reset the dma channels we will use */
+	/* reset the dma channels we will use */
 
 	RESET_DMA(ATA_TX_DMA_NBR);
 	RESET_DMA(ATA_RX_DMA_NBR);
@@ -657,10 +750,9 @@
                 }
 		/* ok we want to do IO at addr, size bytes. set up a new descriptor entry */
                 if(size == 65536) {
-                  ata_descrs[count].sw_len = 0;  /* 0 means 65536, this is a 16-bit field */
-                }
-                else {
-                  ata_descrs[count].sw_len = size;
+			ata_descrs[count].sw_len = 0;  /* 0 means 65536, this is a 16-bit field */
+                } else {
+			ata_descrs[count].sw_len = size;
                 }
 		ata_descrs[count].ctrl = 0;
 		ata_descrs[count].buf = addr;
@@ -823,7 +915,15 @@
 		}
 
 		/* begin DMA */
-	      
+		
+		/* need to do this before RX DMA due to a chip bug
+		 * it is enough to just flush the part of the cache that
+		 * corresponds to the buffers we start, but since HD transfers
+		 * usually are more than 8 kB, it is easier to optimize for the
+		 * normal case and just flush the entire cache. its the only
+		 * way to be sure! (OB movie quote)
+		 */
+		flush_etrax_cache();  
 		*R_DMA_CH3_FIRST = virt_to_phys(ata_descrs);
 		*R_DMA_CH3_CMD   = IO_STATE(R_DMA_CH3_CMD, cmd, start);
 		
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/cris/drivers/lpslave/e100lpslavenet.c linux/arch/cris/drivers/lpslave/e100lpslavenet.c
--- linux.orig/arch/cris/drivers/lpslave/e100lpslavenet.c	Thu Jul 26 22:10:06 2001
+++ linux/arch/cris/drivers/lpslave/e100lpslavenet.c	Tue May 28 22:39:24 2002
@@ -1,4 +1,4 @@
-/* $Id: e100lpslavenet.c,v 1.4 2001/06/21 16:55:26 olof Exp $
+/* $Id: e100lpslavenet.c,v 1.5 2002/04/22 11:47:24 johana Exp $
  *
  * e100lpslavenet.c: A network driver for the ETRAX 100LX slave controller.
  *
@@ -7,6 +7,12 @@
  * The outline of this driver comes from skeleton.c.
  *
  * $Log: e100lpslavenet.c,v $
+ * Revision 1.5  2002/04/22 11:47:24  johana
+ * Fix according to 2.4.19-pre7. time_after/time_before and
+ * missing end of comment.
+ * The patch has a typo for ethernet.c in e100_clear_network_leds(),
+ *  that is fixed here.
+ *
  * Revision 1.4  2001/06/21 16:55:26  olof
  * Minimized par port setup time to gain bandwidth
  *
@@ -310,7 +316,7 @@
 		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 /
+          /* 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)    |
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/cris/drivers/parport.c linux/arch/cris/drivers/parport.c
--- linux.orig/arch/cris/drivers/parport.c	Mon Oct  8 18:43:54 2001
+++ linux/arch/cris/drivers/parport.c	Tue May 28 22:39:15 2002
@@ -1,4 +1,4 @@
-/* $Id: parport.c,v 1.8 2001/09/26 11:51:52 bjornw Exp $
+/* $Id: parport.c,v 1.9 2002/05/15 12:30:24 starvik Exp $
  * 
  * Elinux parallel port driver
  * NOTE!
@@ -204,7 +204,7 @@
 	SETF(info->reg_ctrl_data_shadow, R_PAR0_CTRL_DATA, autofd,
 	     (control & PARPORT_CONTROL_AUTOFD) > 0);
 	SETF(info->reg_ctrl_data_shadow, R_PAR0_CTRL_DATA, init,
-	     (control & PARPORT_CONTROL_INIT) > 0);
+	     (control & PARPORT_CONTROL_INIT) == 0);
 	SETF(info->reg_ctrl_data_shadow, R_PAR0_CTRL_DATA, seli,
 	     (control & PARPORT_CONTROL_SELECT) > 0);
 
@@ -223,7 +223,7 @@
 		ret |= PARPORT_CONTROL_STROBE;
 	if (IO_EXTRACT(R_PAR0_CTRL_DATA, autofd, info->reg_ctrl_data_shadow))
 		ret |= PARPORT_CONTROL_AUTOFD;
-	if (IO_EXTRACT(R_PAR0_CTRL_DATA, init, info->reg_ctrl_data_shadow))
+	if (!IO_EXTRACT(R_PAR0_CTRL_DATA, init, info->reg_ctrl_data_shadow))
 		ret |= PARPORT_CONTROL_INIT;
 	if (IO_EXTRACT(R_PAR0_CTRL_DATA, seli, info->reg_ctrl_data_shadow))
 		ret |= PARPORT_CONTROL_SELECT;
@@ -258,7 +258,7 @@
 		ret |= PARPORT_STATUS_ERROR;
 	if (IO_EXTRACT(R_PAR0_STATUS_DATA, sel, *info->reg_status_data))
 		ret |= PARPORT_STATUS_SELECT;
-	if (!IO_EXTRACT(R_PAR0_STATUS_DATA, perr, *info->reg_status_data))
+	if (IO_EXTRACT(R_PAR0_STATUS_DATA, perr, *info->reg_status_data))
 		ret |= PARPORT_STATUS_PAPEROUT;
 	if (IO_EXTRACT(R_PAR0_STATUS_DATA, ack, *info->reg_status_data))
 		ret |= PARPORT_STATUS_ACK;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/cris/drivers/serial.c linux/arch/cris/drivers/serial.c
--- linux.orig/arch/cris/drivers/serial.c	Mon Feb 25 19:37:52 2002
+++ linux/arch/cris/drivers/serial.c	Tue May 28 22:39:16 2002
@@ -1,12 +1,24 @@
-/* $Id: serial.c,v 1.29 2002/01/14 16:10:01 pkj Exp $
+/* $Id: serial.c,v 1.32 2002/05/22 13:58:00 johana Exp $
  *
  * Serial port driver for the ETRAX 100LX chip
  *
- *      Copyright (C) 1998, 1999, 2000, 2001  Axis Communications AB
+ *      Copyright (C) 1998, 1999, 2000, 2001, 2002  Axis Communications AB
  *
  *      Many, many authors. Based once upon a time on serial.c for 16x50.
  *
  * $Log: serial.c,v $
+ * Revision 1.32  2002/05/22 13:58:00  johana
+ * Renamed rs_write() to raw_write() and made it inline.
+ * New rs_write() handles RS-485 if configured and enabled
+ * (moved code from e100_write_rs485()).
+ * RS-485 ioctl's uses copy_from_user() instead of verify_area().
+ *
+ * Revision 1.31  2002/04/22 11:20:03  johana
+ * Updated copyright years.
+ *
+ * Revision 1.30  2002/04/22 09:39:12  johana
+ * RS-485 support compiles.
+ *
  * Revision 1.29  2002/01/14 16:10:01  pkj
  * Allocate the receive buffers dynamically. The static 4kB buffer was
  * too small for the peaks. This means that we can get rid of the extra
@@ -291,7 +303,7 @@
  *
  */
 
-static char *serial_version = "$Revision: 1.29 $";
+static char *serial_version = "$Revision: 1.32 $";
 
 #include <linux/config.h>
 #include <linux/version.h>
@@ -322,7 +334,7 @@
 #include <asm/system.h>
 #include <asm/segment.h>
 #include <asm/bitops.h>
-#include <asm/delay.h>
+#include <linux/delay.h>
 
 #include <asm/svinto.h>
 
@@ -390,6 +402,13 @@
 static void rs_wait_until_sent(struct tty_struct *tty, int timeout);
 static int rs_write(struct tty_struct * tty, int from_user,
                     const unsigned char *buf, int count);
+static inline int raw_write(struct tty_struct * tty, int from_user,
+                            const unsigned char *buf, int count);
+static int e100_write_rs485(struct tty_struct * tty, int from_user,
+                            const unsigned char *buf, int count);
+static int 
+get_lsr_info(struct e100_serial * info, unsigned int *value);
+
 
 #define DEF_BAUD 0x99   /* 115.2 kbit/s */
 #define STD_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
@@ -827,12 +846,12 @@
 e100_rts(struct e100_serial *info, int set)
 {
 #ifndef CONFIG_SVINTO_SIM
-#ifdef SERIAL_DEBUG_IO  
-	printk("ser%i rts %i\n", info->line, set);
-#endif
 	info->rx_ctrl &= ~E100_RTS_MASK;
 	info->rx_ctrl |= (set ? 0 : E100_RTS_MASK);  /* RTS is active low */
 	info->port[REG_REC_CTRL] = info->rx_ctrl;
+#ifdef SERIAL_DEBUG_IO  
+	printk("ser%i rts %i\n", info->line, set);
+#endif
 #endif
 }
 
@@ -985,63 +1004,32 @@
 	info->rs485.rts_after_sent = 0x01 & r->rts_after_sent;
 	info->rs485.delay_rts_before_send = r->delay_rts_before_send;
 	info->rs485.enabled = r->enabled;
-	
+/*	printk("rts: on send = %i, after = %i, enabled = %i",
+		    info->rs485.rts_on_send,
+		    info->rs485.rts_after_sent,
+		    info->rs485.enabled
+	);
+*/		
 	return 0;
 }
 
 static int
-e100_write_rs485(struct tty_struct *tty,struct rs485_write *r)
+e100_write_rs485(struct tty_struct *tty, int from_user, 
+                 const unsigned char *buf, int count)
 {
-	int total;
 	struct e100_serial * info = (struct e100_serial *)tty->driver_data;
+	int old_enabled = info->rs485.enabled;
 
-	/* If we are in RS-485 mode, we need to toggle RTS and disable
-	 * the receiver before initiating a DMA transfer
-	 */
-	e100_rts(info, info->rs485.rts_on_send);
-#if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER)
-	e100_disable_rx(info);
-	e100_disable_rxdma_irq(info);
-#endif
-
-	if (info->rs485.delay_rts_before_send > 0) {
-		current->timeout = jiffies + (info->rs485.delay_rts_before_send * HZ)/1000;
-		current->state = TASK_INTERRUPTIBLE;
-		schedule();
-		current->timeout = 0;
-	}
-	total = rs_write(tty, 1, (*r).outc, (*r).outc_size);
-
-	/* If we are in RS-485 mode the following things has to be done:
-	 * wait until DMA is ready
-	 * wait on transmit shift register
-	 * wait to toggle RTS
-	 * enable the receiver
-	 */	
-
-	/* Sleep until all sent */
-	tty_wait_until_sent(tty, 0);
-#ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER
-	/* Now sleep a little more so that shift register is empty */
-	schedule_usleep(info->char_time_usec * 2);
-#else
-	{
-		unsigned int val;
-		/* wait on transmit shift register */
-		do{
-			get_lsr_info(info, &val);
-		}while (!(val & TIOCSER_TEMT));
-	}
-#endif
-
-	e100_rts(info, info->rs485.rts_after_sent);
-	
-#if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER)
-	e100_enable_rx(info);
-	e100_enable_rxdma_irq(info);
-#endif
-
-	return total;
+	/* rs485 is always implicitly enabled if we're using the ioctl() 
+	 * but it doesn't have to be set in the rs485_control
+	 * (to be backward compatible with old apps)
+	 * So we store, set and restore it.
+	 */
+	info->rs485.enabled = 1;
+	/* rs_write now deals with RS485 if enabled */
+	count = rs_write(tty, from_user, buf, count);
+	info->rs485.enabled = old_enabled;
+	return count;
 }
 #endif
 
@@ -1186,26 +1174,6 @@
 		/* our job here is done, don't schedule any new DMA transfer */
 		info->tr_running = 0;
 
-#if defined(CONFIG_ETRAX_RS485)
-		/* Check if we should toggle RTS now */
-		if (info->rs485.enabled) {
-			/* Make sure fifo is empty */
-			int in_fifo = 0;
-
-			do {
-				in_fifo = IO_EXTRACT(R_DMA_CH6_STATUS, avail,
-						     *info->ostatusadr);
-			}  while (in_fifo > 0);
-			/* Any way to really check transmitter empty? (TEMT) */
-			/* Control RTS to set to RX mode */
-			e100_rts(info, info->rs485.rts_after_sent); 
-#if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER)
-			e100_enable_rx(info);
-			e100_enable_rxdma_irq(info);
-#endif
-		}
-#endif /* RS485 */
-
 		return;
 	}
 
@@ -2352,8 +2320,8 @@
 	restore_flags(flags);
 }
 
-static int 
-rs_write(struct tty_struct * tty, int from_user,
+static inline int 
+raw_write(struct tty_struct * tty, int from_user,
 	 const unsigned char *buf, int count)
 {
 	int	c, ret = 0;
@@ -2367,7 +2335,7 @@
 	
 #ifdef SERIAL_DEBUG_DATA
 	if (info->line == SERIAL_DEBUG_LINE)
-		printk("rs_write (%d), status %d\n", 
+		printk("raw_write (%d), status %d\n", 
 		       count, info->port[REG_STATUS]);
 #endif
 
@@ -2453,8 +2421,70 @@
 	}
  	
 	return ret;
+} /* raw_write() */
+
+static int 
+rs_write(struct tty_struct * tty, int from_user,
+	 const unsigned char *buf, int count)
+{
+#if defined(CONFIG_ETRAX_RS485)
+	struct e100_serial *info = (struct e100_serial *)tty->driver_data;
+
+	if (info->rs485.enabled)
+	{
+		/* If we are in RS-485 mode, we need to toggle RTS and disable
+		 * the receiver before initiating a DMA transfer
+		 */
+		e100_rts(info, info->rs485.rts_on_send);
+#if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER)
+		e100_disable_rx(info);
+		e100_disable_rxdma_irq(info);
+#endif
+
+		if (info->rs485.delay_rts_before_send > 0) {
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout((info->rs485.delay_rts_before_send * HZ)/1000);
+		}
+	}
+#endif /* CONFIG_ETRAX_RS485 */
+
+	count = raw_write(tty, from_user, buf, count);
+
+#if defined(CONFIG_ETRAX_RS485)
+	if (info->rs485.enabled)
+	{
+		unsigned int val;
+		/* If we are in RS-485 mode the following has to be done:
+		 * wait until DMA is ready
+		 * wait on transmit shift register
+		 * toggle RTS
+		 * enable the receiver
+		 */	
+
+		/* Sleep until all sent */
+		tty_wait_until_sent(tty, 0);
+#ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER
+		/* Now sleep a little more so that shift register is empty */
+		schedule_usleep(info->char_time_usec * 2);
+#endif
+		/* wait on transmit shift register */
+		do{
+			get_lsr_info(info, &val);
+		}while (!(val & TIOCSER_TEMT));
+
+		e100_rts(info, info->rs485.rts_after_sent);
+	
+#if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER)
+		e100_enable_rx(info);
+		e100_enable_rxdma_irq(info);
+#endif
+	}
+#endif /* CONFIG_ETRAX_RS485 */
+
+	return count;
 }
 
+
 /* how much space is available in the xmit buffer? */
 
 static int 
@@ -2882,7 +2912,7 @@
 	 unsigned int cmd, unsigned long arg)
 {
 	struct e100_serial * info = (struct e100_serial *)tty->driver_data;
-#if defined(CONFIG_ETRAX_RS485) || (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */
+#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */
 	int error;
 #endif
 #if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */
@@ -2959,22 +2989,22 @@
 
 #if defined(CONFIG_ETRAX_RS485)
 		case TIOCSERSETRS485:
-			error = verify_area(VERIFY_WRITE, (void *) arg,
-					sizeof(struct rs485_control));
-			
-			if (error)
-				return error;
-			
-			return e100_enable_rs485(tty, (struct rs485_control *) arg);
+		{
+			struct rs485_control rs485ctrl;
+			if (copy_from_user(&rs485ctrl, (struct rs485_control*)arg, sizeof(rs485ctrl)))
+				return -EFAULT;
+
+			return e100_enable_rs485(tty, &rs485ctrl);
+		}
 
 		case TIOCSERWRRS485:
-			error = verify_area(VERIFY_WRITE, (void *) arg,
-					sizeof(struct rs485_write));
-			
-			if (error)
-				return error;
-			
-			return e100_write_rs485(tty, (struct rs485_write *) arg);
+		{
+			struct rs485_write rs485wr;
+			if (copy_from_user(&rs485wr, (struct rs485_write*)arg, sizeof(rs485wr)))
+				return -EFAULT;
+
+			return e100_write_rs485(tty, 1, rs485wr.outc, rs485wr.outc_size);
+		}
 #endif
 			
 		default:
@@ -3518,8 +3548,8 @@
 static void 
 show_serial_version(void)
 {
-	printk("ETRAX 100LX serial-driver %s, (c) 2000 Axis Communications AB\r\n",
-	       serial_version);
+	printk("ETRAX 100LX serial-driver %s, (c) 2000-2002 Axis Communications AB\r\n",
+	       &serial_version[11]); /* "$Revision: x.yy" */
 }
 
 /* rs_init inits the driver at boot (using the module_init chain) */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/cris/drivers/serial.h linux/arch/cris/drivers/serial.h
--- linux.orig/arch/cris/drivers/serial.h	Mon Feb 25 19:37:52 2002
+++ linux/arch/cris/drivers/serial.h	Tue May 28 22:39:23 2002
@@ -116,7 +116,7 @@
 	int			break_detected_cnt;
 	int			errorcode;
 
-#ifdef CONFIG_RS485
+#ifdef CONFIG_ETRAX_RS485
 	struct rs485_control	rs485;  /* RS-485 support */
 #endif
 };
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/cris/drivers/sync_serial.c linux/arch/cris/drivers/sync_serial.c
--- linux.orig/arch/cris/drivers/sync_serial.c	Mon Feb 25 19:37:52 2002
+++ linux/arch/cris/drivers/sync_serial.c	Tue May 28 22:39:16 2002
@@ -199,7 +199,6 @@
 	/* Deselect synchronous serial ports */
 	SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, async);
 	SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, async);
-	SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, ser3, select);
 	*R_GEN_CONFIG_II = gen_config_ii_shadow;
   
 	/* Initialize Ports */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/cris/kernel/debugport.c linux/arch/cris/kernel/debugport.c
--- linux.orig/arch/cris/kernel/debugport.c	Tue May  1 23:04:56 2001
+++ linux/arch/cris/kernel/debugport.c	Tue May 28 22:39:14 2002
@@ -12,6 +12,9 @@
  *    init_etrax_debug()
  *
  * $Log: debugport.c,v $
+ * Revision 1.7  2002/04/23 15:35:50  bjornw
+ * Cleaned up sercons struct and removed the waitkey ptr (2.4.19-pre)
+ *
  * Revision 1.6  2001/04/17 13:58:39  orjanf
  * * Renamed CONFIG_KGDB to CONFIG_ETRAX_KGDB.
  *
@@ -224,17 +227,16 @@
 }
 
 static struct console sercons = {
-        "ttyS",
-        console_write,
-        NULL,
-        console_device,
-        NULL,
-	NULL,
-	console_setup,
-	CON_PRINTBUFFER,
-	DEBUG_PORT_IDX,
-	0,
-	NULL
+        name : "ttyS",
+        write: console_write,
+        read : NULL,
+        device : console_device,
+	unblank : NULL,
+	setup : console_setup,
+	flags : CON_PRINTBUFFER,
+	index : DEBUG_PORT_IDX,
+	cflag : 0,
+	next : NULL
 };
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/cris/kernel/entry.S linux/arch/cris/kernel/entry.S
--- linux.orig/arch/cris/kernel/entry.S	Mon Feb 25 19:37:52 2002
+++ linux/arch/cris/kernel/entry.S	Tue May 28 22:39:25 2002
@@ -1,12 +1,15 @@
-/* $Id: entry.S,v 1.38 2002/01/16 15:15:30 bjornw Exp $
+/* $Id: entry.S,v 1.39 2002/04/24 00:46:45 bjornw Exp $
  *
  *  linux/arch/cris/entry.S
  *
- *  Copyright (C) 2000, 2001 Axis Communications AB
+ *  Copyright (C) 2000, 2001, 2002 Axis Communications AB
  *
  *  Authors:	Bjorn Wesen (bjornw@axis.com)
  *
  *  $Log: entry.S,v $
+ *  Revision 1.39  2002/04/24 00:46:45  bjornw
+ *  Added sys_tkill
+ *
  *  Revision 1.38  2002/01/16 15:15:30  bjornw
  *  Use a C-code compatible watchdog reset when NICE_DOGGY is enabled
  *
@@ -1013,7 +1016,8 @@
         .long SYMBOL_NAME(sys_ni_syscall)       /* Reserved for Security */
         .long SYMBOL_NAME(sys_gettid)
         .long SYMBOL_NAME(sys_readahead)        /* 225 */
-
+	.long SYMBOL_NAME(sys_tkill)
+	
         /*
          * NOTE!! This doesn't have to be exact - we just have
          * to make sure we have _enough_ of the "sys_ni_syscall"
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/cris/kernel/head.S linux/arch/cris/kernel/head.S
--- linux.orig/arch/cris/kernel/head.S	Mon Feb 25 19:37:52 2002
+++ linux/arch/cris/kernel/head.S	Tue May 28 22:39:24 2002
@@ -1,4 +1,4 @@
-/* $Id: head.S,v 1.43 2001/11/08 15:09:43 starvik Exp $
+/* $Id: head.S,v 1.44 2002/02/05 15:39:57 bjornw Exp $
  * 
  * Head of the kernel - alter with care
  *
@@ -7,6 +7,9 @@
  * Authors:	Bjorn Wesen (bjornw@axis.com)
  * 
  * $Log: head.S,v $
+ * Revision 1.44  2002/02/05 15:39:57  bjornw
+ * Oops.. non-CRAMFS_MAGIC should jump over the copying, not into it...
+ *
  * Revision 1.43  2001/11/08 15:09:43  starvik
  * Only start MII clock if Ethernet is configured
  *
@@ -420,7 +423,7 @@
 	move.d	__vmlinux_end, $r0; the image will be after the vmlinux end address
 	move.d	[$r0], $r1	; cramfs assumes same endian on host/target
 	cmp.d	CRAMFS_MAGIC, $r1; magic value in cramfs superblock
-	bne	1f
+	bne	2f
 	nop
 
 	;; Ok. What is its size ? 
@@ -450,7 +453,8 @@
 	subq	1, $r2
 	bne	1b
 	nop
-	
+
+2:	
 	;; Dont worry that the BSS is tainted. It will be cleared later.
 
 	moveq	0, $r0
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/cris/kernel/signal.c linux/arch/cris/kernel/signal.c
--- linux.orig/arch/cris/kernel/signal.c	Mon Oct  8 18:43:54 2001
+++ linux/arch/cris/kernel/signal.c	Tue May 28 22:39:14 2002
@@ -7,7 +7,7 @@
  *
  *  Ideas also taken from arch/arm.
  *
- *  Copyright (C) 2000, 2001 Axis Communications AB
+ *  Copyright (C) 2000, 2001, 2002 Axis Communications AB
  *
  *  Authors:  Bjorn Wesen (bjornw@axis.com)
  *
@@ -679,10 +679,7 @@
 
 			default:
 				lock_kernel();
-				sigaddset(&current->pending.signal, signr);
-				recalc_sigpending(current);
-				current->flags |= PF_SIGNALED;
-				do_exit(exit_code);
+				sig_exit(signr, exit_code, &info);
 				/* NOTREACHED */
 			}
 		}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/cris/kernel/time.c linux/arch/cris/kernel/time.c
--- linux.orig/arch/cris/kernel/time.c	Mon Feb 25 19:37:52 2002
+++ linux/arch/cris/kernel/time.c	Tue May 28 22:39:13 2002
@@ -1,4 +1,4 @@
-/* $Id: time.c,v 1.11 2001/11/12 18:26:22 pkj Exp $
+/* $Id: time.c,v 1.14 2002/03/05 13:31:03 johana Exp $
  *
  *  linux/arch/cris/kernel/time.c
  *
@@ -19,6 +19,12 @@
  *
  * Authors:    Bjorn Wesen
  *             Johan Adolfsson  
+ * 2002-03-04    Johan Adolfsson
+ *      Use prescale timer at 25000 Hz instead of the baudrate timer at 
+ *      19200 to get rid of the 64ppm to fast timer (and we get better 
+ *      resolution within a jiffie as well.
+ * 2002-03-05    Johan Adolfsson
+ *      Use prescaler in do_slow_gettimeoffset() to get 1 us resolution (40ns)
  *
  */
 
@@ -44,6 +50,8 @@
 
 #include <asm/svinto.h>
 
+#define CRIS_TEST_TIMERS 0
+
 static int have_rtc;  /* used to remember if we have an RTC or not */
 
 /* define this if you need to use print_timestamp */
@@ -52,19 +60,85 @@
 
 extern int setup_etrax_irq(int, struct irqaction *);
 
-/* Lookup table to convert *R_TIMER0 to microseconds (us) 
- * Timer goes from TIMER0_DIV down to 1 meaning 0-10000us in step of approx 52us
- */
-unsigned short cris_timer0_value_us[TIMER0_DIV+1];
-
 #define TICK_SIZE tick
 
+/* The timers count from their initial value down to 1 
+ * The R_TIMER0_DATA counts down when R_TIM_PRESC_STATUS reaches halv
+ * of the divider value.
+ */ 
+unsigned long get_ns_in_jiffie(void)
+{
+	unsigned char timer_count, t1;
+	unsigned short presc_count;
+	unsigned long ns;
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();	
+	timer_count = *R_TIMER0_DATA;
+	presc_count = *R_TIM_PRESC_STATUS;  
+	/* presc_count might be wrapped */
+	t1 = *R_TIMER0_DATA;
+
+	if (timer_count != t1){
+		/* it wrapped, read prescaler again...  */
+		presc_count = *R_TIM_PRESC_STATUS;
+		timer_count = t1;
+	}
+	restore_flags(flags);
+	if (presc_count >= PRESCALE_VALUE/2 ){
+		presc_count =  PRESCALE_VALUE - presc_count + PRESCALE_VALUE/2;
+	} else {
+		presc_count =  PRESCALE_VALUE - presc_count - PRESCALE_VALUE/2;
+	}
+
+	ns = ( (TIMER0_DIV - timer_count) * ((1000000000/HZ)/TIMER0_DIV )) + 
+	     ( (presc_count) * (1000000000/PRESCALE_FREQ));
+	return ns;
+}
+
+
+
+#if CRIS_TEST_TIMERS 
+#define NS_TEST_SIZE 4000
+static unsigned long ns_test[NS_TEST_SIZE];
+void cris_test_timers(void)
+{
+	int i;
+#if 0
+	for (i = 0; i < NS_TEST_SIZE; i++)
+	{
+		ns_test[i] = *R_TIMER0_DATA | (*R_TIM_PRESC_STATUS<<16);
+	}
+	for (i = 1; i < NS_TEST_SIZE; i++)
+	{
+		printk("%4i. %lu %lu %09lu ns \n",
+		       i, ns_test[i]&0x0FFFF, (ns_test[i]>>16), 
+	get_ns_in_jiffie_from_data(ns_test[i]&0x0FFFF, ns_test[i]>>16));
+	}
+#else
+	for (i = 0; i < NS_TEST_SIZE; i++)
+	{
+		ns_test[i] = get_ns_in_jiffie();
+	}
+
+	for (i = 1; i < NS_TEST_SIZE; i++)
+	{
+		printk("%4i. %09lu ns diff %li ns\n",
+		       i, ns_test[i], ns_test[i]- ns_test[i-1]);
+	}
+#endif
+}
+
+#endif
+
 static unsigned long do_slow_gettimeoffset(void)
 {
-	unsigned long count;
+	unsigned long count, t1;
 	unsigned long usec_count = 0;
+	unsigned short presc_count;
 
-	static unsigned long count_p = LATCH;    /* for the first call after boot */
+	static unsigned long count_p = TIMER0_DIV;/* for the first call after boot */
 	static unsigned long jiffies_p = 0;
 
 	/*
@@ -80,8 +154,17 @@
 #ifndef CONFIG_SVINTO_SIM
 	/* Not available in the xsim simulator. */
 	count = *R_TIMER0_DATA;
+	presc_count = *R_TIM_PRESC_STATUS;  
+	/* presc_count might be wrapped */
+	t1 = *R_TIMER0_DATA;
+	if (count != t1){
+		/* it wrapped, read prescaler again...  */
+		presc_count = *R_TIM_PRESC_STATUS;
+		count = t1;
+	}
 #else
 	count = 0;
+	presc_count = 0;
 #endif
 
  	jiffies_t = jiffies;
@@ -92,22 +175,26 @@
 	 *  1. the timer counter underflows
 	 *  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 ) {
-			/* Timer wrapped */
-			count = count_p;
-			usec_count = 1000000/CLOCK_TICK_RATE/2;
+			/* Timer wrapped, use new count and prescale 
+			 * increase the time corresponding to one jiffie
+			 */
+			usec_count = 1000000/HZ;
 		}
 	} else
 		jiffies_p = jiffies_t;
         count_p = count;
-	/* Convert timer value to usec using table lookup */
-	usec_count += cris_timer0_value_us[count];
-#if 0
-	count = ((LATCH-1) - count) * TICK_SIZE;
-	count = (count + LATCH/2) / LATCH;
-#endif
+	if (presc_count >= PRESCALE_VALUE/2 ){
+		presc_count =  PRESCALE_VALUE - presc_count + PRESCALE_VALUE/2;
+	} else {
+		presc_count =  PRESCALE_VALUE - presc_count - PRESCALE_VALUE/2;
+	}
+	/* Convert timer value to usec */
+	usec_count += ( (TIMER0_DIV - count) * (1000000/HZ)/TIMER0_DIV ) +
+	              (( (presc_count) * (1000000000/PRESCALE_FREQ))/1000);
+
 	return usec_count;
 }
 
@@ -124,11 +211,11 @@
 	cli();
 	*tv = xtime;
 	tv->tv_usec += do_gettimeoffset();
-	if (tv->tv_usec >= 1000000) {
+	restore_flags(flags);
+	while (tv->tv_usec >= 1000000) {
 		tv->tv_usec -= 1000000;
 		tv->tv_sec++;
 	}
-	restore_flags(flags);
 }
 
 void do_settimeofday(struct timeval *tv)
@@ -392,7 +479,6 @@
 void __init
 time_init(void)
 {	
-	int i;
 	/* probe for the RTC and read it if it exists */
 
 	if(RTC_INIT() < 0) {
@@ -435,33 +521,33 @@
 		IO_STATE( R_TIMER_CTRL, tm0, run) |
 		IO_STATE( R_TIMER_CTRL, clksel0, c6250kHz);
 #else
+  
 	*R_TIMER_CTRL = 
 		IO_FIELD(R_TIMER_CTRL, timerdiv1, 192)      | 
-		IO_FIELD(R_TIMER_CTRL, timerdiv0, 192)      |
+		IO_FIELD(R_TIMER_CTRL, timerdiv0, TIMER0_DIV)      |
 		IO_STATE(R_TIMER_CTRL, i1,        nop)      | 
 		IO_STATE(R_TIMER_CTRL, tm1,       stop_ld)  |
 		IO_STATE(R_TIMER_CTRL, clksel1,   c19k2Hz)  |
 		IO_STATE(R_TIMER_CTRL, i0,        nop)      |
 		IO_STATE(R_TIMER_CTRL, tm0,       stop_ld)  |
-		IO_STATE(R_TIMER_CTRL, clksel0,   c19k2Hz);
+		IO_STATE(R_TIMER_CTRL, clksel0,   flexible);
 	
 	*R_TIMER_CTRL = r_timer_ctrl_shadow =
 		IO_FIELD(R_TIMER_CTRL, timerdiv1, 192)      | 
-		IO_FIELD(R_TIMER_CTRL, timerdiv0, 192)      |
+		IO_FIELD(R_TIMER_CTRL, timerdiv0, TIMER0_DIV)      |
 		IO_STATE(R_TIMER_CTRL, i1,        nop)      |
 		IO_STATE(R_TIMER_CTRL, tm1,       run)      |
 		IO_STATE(R_TIMER_CTRL, clksel1,   c19k2Hz)  |
 		IO_STATE(R_TIMER_CTRL, i0,        nop)      |
 		IO_STATE(R_TIMER_CTRL, tm0,       run)      |
-		IO_STATE(R_TIMER_CTRL, clksel0,   c19k2Hz);
+		IO_STATE(R_TIMER_CTRL, clksel0,   flexible);
+
+	*R_TIMER_PRESCALE = PRESCALE_VALUE;
 #endif
 
-	for (i=0; i <= TIMER0_DIV; i++) {
-		/* We must be careful not to get overflow... */
-		cris_timer0_value_us[TIMER0_DIV-i] = 
-		  (unsigned short)((unsigned long)
-		  ((i*(1000000/HZ))/TIMER0_DIV)&0x0000FFFFL);
-	}
+#if CRIS_TEST_TIMERS
+	cris_test_timers();
+#endif
 	
 	*R_IRQ_MASK0_SET =
 		IO_STATE(R_IRQ_MASK0_SET, timer0, set); /* unmask the timer irq */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/cris/mm/extable.c linux/arch/cris/mm/extable.c
--- linux.orig/arch/cris/mm/extable.c	Mon Oct  8 18:43:54 2001
+++ linux/arch/cris/mm/extable.c	Tue May 28 22:39:28 2002
@@ -2,6 +2,9 @@
  * linux/arch/cris/mm/extable.c
  *
  * $Log: extable.c,v $
+ * Revision 1.4  2002/03/19 15:21:10  bjornw
+ * Fixed warning
+ *
  * Revision 1.3  2001/09/27 13:52:40  bjornw
  * Harmonize underscore-ness with other parts
  *
@@ -39,13 +42,12 @@
 unsigned long
 search_exception_table(unsigned long addr)
 {
-	unsigned long ret;
-
 #ifndef CONFIG_MODULES
 	/* There is only the kernel to search.  */
 	return search_one_table(__start___ex_table, __stop___ex_table-1, addr);
 #else
 	/* The kernel is the last "module" -- no need to treat it special.  */
+	unsigned long ret;
 	struct module *mp;
 	for (mp = module_list; mp != NULL; mp = mp->next) {
 		if (mp->ex_table_start == NULL)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/cris/mm/fault.c linux/arch/cris/mm/fault.c
--- linux.orig/arch/cris/mm/fault.c	Mon Feb 25 19:37:52 2002
+++ linux/arch/cris/mm/fault.c	Tue May 28 22:39:22 2002
@@ -437,7 +437,7 @@
 	 * Send a sigbus, regardless of whether we were in kernel
 	 * or user mode.
 	 */
-	info.si_code = SIGBUS;
+	info.si_signo = SIGBUS;
 	info.si_errno = 0;
 	info.si_code = BUS_ADRERR;
 	info.si_addr = (void *)address;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/cris/mm/init.c linux/arch/cris/mm/init.c
--- linux.orig/arch/cris/mm/init.c	Mon Feb 25 19:37:52 2002
+++ linux/arch/cris/mm/init.c	Tue May 28 22:39:26 2002
@@ -7,6 +7,18 @@
  *  Authors:  Bjorn Wesen (bjornw@axis.com)
  *
  *  $Log: init.c,v $
+ *  Revision 1.35  2002/05/17 05:33:59  starvik
+ *  Limit cache flush range to the size of the cache
+ *
+ *  Revision 1.34  2002/04/22 11:48:51  johana
+ *  Added KERN_INFO (2.4.19-pre7)
+ *
+ *  Revision 1.33  2002/03/19 15:22:17  bjornw
+ *  Added flush_etrax_cache
+ *
+ *  Revision 1.32  2002/03/15 17:09:31  bjornw
+ *  Added prepare_rx_descriptor as a workaround for a bug
+ *
  *  Revision 1.31  2001/11/13 16:22:00  bjornw
  *  Skip calculating totalram and sharedram in si_meminfo
  *
@@ -219,13 +231,15 @@
 #ifndef CONFIG_CRIS_LOW_MAP
 	/* This code is for the corrected Etrax-100 LX version 2... */
 
+#define CACHED_BOOTROM (KSEG_A | 0x08000000UL)
+
 	*R_MMU_KSEG = ( IO_STATE(R_MMU_KSEG, seg_f, seg  ) | /* cached flash */
 			IO_STATE(R_MMU_KSEG, seg_e, seg  ) | /* uncached flash */
 			IO_STATE(R_MMU_KSEG, seg_d, page ) | /* vmalloc area */
 			IO_STATE(R_MMU_KSEG, seg_c, seg  ) | /* kernel area */
 			IO_STATE(R_MMU_KSEG, seg_b, seg  ) | /* kernel reg area */
-			IO_STATE(R_MMU_KSEG, seg_a, page ) | /* user area */
-			IO_STATE(R_MMU_KSEG, seg_9, page ) |
+			IO_STATE(R_MMU_KSEG, seg_a, seg  ) | /* bootrom/regs cached */ 
+			IO_STATE(R_MMU_KSEG, seg_9, page ) | /* user area */
 			IO_STATE(R_MMU_KSEG, seg_8, page ) |
 			IO_STATE(R_MMU_KSEG, seg_7, page ) |
 			IO_STATE(R_MMU_KSEG, seg_6, page ) |
@@ -241,7 +255,7 @@
 			    IO_FIELD(R_MMU_KBASE_HI, base_d, 0x0 ) |
 			    IO_FIELD(R_MMU_KBASE_HI, base_c, 0x4 ) |
 			    IO_FIELD(R_MMU_KBASE_HI, base_b, 0xb ) |
-			    IO_FIELD(R_MMU_KBASE_HI, base_a, 0x0 ) |
+			    IO_FIELD(R_MMU_KBASE_HI, base_a, 0x3 ) |
 			    IO_FIELD(R_MMU_KBASE_HI, base_9, 0x0 ) |
 			    IO_FIELD(R_MMU_KBASE_HI, base_8, 0x0 ) );
 	
@@ -268,7 +282,9 @@
 	 * We map them straight over in LOW_MAP, but use vremap in LX version 2.
 	 */
 
-	*R_MMU_KSEG = ( IO_STATE(R_MMU_KSEG, seg_f, page ) | 
+#define CACHED_BOOTROM (KSEG_F | 0x08000000UL)
+
+	*R_MMU_KSEG = ( IO_STATE(R_MMU_KSEG, seg_f, seg  ) |  /* cached bootrom/regs */ 
 			IO_STATE(R_MMU_KSEG, seg_e, page ) |
 			IO_STATE(R_MMU_KSEG, seg_d, page ) | 
 			IO_STATE(R_MMU_KSEG, seg_c, page ) |   
@@ -289,7 +305,7 @@
 			IO_STATE(R_MMU_KSEG, seg_1, page ) |  /* user area */
 			IO_STATE(R_MMU_KSEG, seg_0, page ) ); /* user area */
 
-	*R_MMU_KBASE_HI = ( IO_FIELD(R_MMU_KBASE_HI, base_f, 0x0 ) |
+	*R_MMU_KBASE_HI = ( IO_FIELD(R_MMU_KBASE_HI, base_f, 0x3 ) |
 			    IO_FIELD(R_MMU_KBASE_HI, base_e, 0x0 ) |
 			    IO_FIELD(R_MMU_KBASE_HI, base_d, 0x0 ) |
 			    IO_FIELD(R_MMU_KBASE_HI, base_c, 0x0 ) |
@@ -450,6 +466,48 @@
         }
 }
 
+/* Helper function for the two below */
+
+static inline void
+flush_etrax_cacherange(void *startadr, int length)
+{
+	/* CACHED_BOOTROM is mapped to the boot-rom area (cached) which
+	 * we can use to get fast dummy-reads of cachelines
+	 */
+
+	volatile short *flushadr = (volatile short *)(((unsigned long)startadr & ~PAGE_MASK) |
+						      CACHED_BOOTROM);
+
+	length = length > 8192 ? 8192 : length;  /* No need to flush more than cache size */
+
+	while(length > 0) {
+		short tmp = *flushadr;           /* dummy read to flush */
+		flushadr += (32/sizeof(short));  /* a cacheline is 32 bytes */
+		length -= 32;
+	}
+}
+
+/* Due to a bug in Etrax100(LX) all versions, receiving DMA buffers
+ * will occationally corrupt certain CPU writes if the DMA buffers
+ * happen to be hot in the cache.
+ * 
+ * As a workaround, we have to flush the relevant parts of the cache
+ * before (re) inserting any receiving descriptor into the DMA HW.
+ */
+
+void
+prepare_rx_descriptor(struct etrax_dma_descr *desc)
+{
+	flush_etrax_cacherange((void *)desc->buf, desc->sw_len ? desc->sw_len : 65536);
+}
+
+/* Do the same thing but flush the entire cache */
+
+void
+flush_etrax_cache(void)
+{
+	flush_etrax_cacherange(0, 8192);
+}
 
 /* free the pages occupied by initialization code */
 
@@ -465,7 +523,7 @@
                 free_page(addr);
                 totalram_pages++;
         }
-        printk ("Freeing unused kernel memory: %luk freed\n", 
+        printk (KERN_INFO "Freeing unused kernel memory: %luk freed\n", 
 		(&__init_end - &__init_begin) >> 10);
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/i386/boot/setup.S linux/arch/i386/boot/setup.S
--- linux.orig/arch/i386/boot/setup.S	Mon Feb 25 19:37:52 2002
+++ linux/arch/i386/boot/setup.S	Tue May 28 22:39:13 2002
@@ -805,7 +805,7 @@
 #
 #	but we yet haven't reloaded the CS register, so the default size 
 #	of the target offset still is 16 bit.
-#       However, using an operant prefix (0x66), the CPU will properly
+#       However, using an operand prefix (0x66), the CPU will properly
 #	take our 48 bit far pointer. (INTeL 80386 Programmer's Reference
 #	Manual, Mixing 16-bit and 32-bit code, page 16-6)
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/i386/config.in linux/arch/i386/config.in
--- linux.orig/arch/i386/config.in	Mon Feb 25 19:37:52 2002
+++ linux/arch/i386/config.in	Tue May 28 22:39:22 2002
@@ -42,7 +42,7 @@
 	 Winchip-C6				CONFIG_MWINCHIPC6 \
 	 Winchip-2				CONFIG_MWINCHIP2 \
 	 Winchip-2A/Winchip-3			CONFIG_MWINCHIP3D \
-	 CyrixIII/C3				CONFIG_MCYRIXIII" Pentium-Pro
+	 CyrixIII/VIA-C3/VIA-C5			CONFIG_MCYRIXIII" Pentium-Pro
 #
 # Define implied options from the CPU selection here
 #
@@ -163,6 +163,9 @@
    define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
    define_bool CONFIG_X86_OOSTORE y
 fi
+
+bool 'Machine Check Exception' CONFIG_X86_MCE
+
 tristate 'Toshiba Laptop support' CONFIG_TOSHIBA
 tristate 'Dell laptop support' CONFIG_I8K
 
@@ -407,9 +410,7 @@
 
 source drivers/usb/Config.in
 
-if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-   source net/bluetooth/Config.in
-fi
+source net/bluetooth/Config.in
 
 mainmenu_option next_comment
 comment 'Kernel hacking'
@@ -421,7 +422,7 @@
    bool '  Memory mapped I/O debugging' CONFIG_DEBUG_IOVIRT
    bool '  Magic SysRq key' CONFIG_MAGIC_SYSRQ
    bool '  Spinlock debugging' CONFIG_DEBUG_SPINLOCK
-   bool '  Verbose BUG() reporting (adds 70K)' CONFIG_DEBUG_BUGVERBOSE
+   bool '  Compile the kernel with frame pointers' CONFIG_FRAME_POINTER
 fi
 
 endmenu
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/i386/defconfig linux/arch/i386/defconfig
--- linux.orig/arch/i386/defconfig	Mon Feb 25 19:37:52 2002
+++ linux/arch/i386/defconfig	Tue May 28 22:39:17 2002
@@ -49,6 +49,7 @@
 CONFIG_X86_GOOD_APIC=y
 CONFIG_X86_PGE=y
 CONFIG_X86_USE_PPRO_CHECKSUM=y
+CONFIG_X86_MCE=y
 # CONFIG_TOSHIBA is not set
 # CONFIG_I8K is not set
 # CONFIG_MICROCODE is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/i386/kernel/acpitable.c linux/arch/i386/kernel/acpitable.c
--- linux.orig/arch/i386/kernel/acpitable.c	Mon Nov 12 03:15:06 2001
+++ linux/arch/i386/kernel/acpitable.c	Tue May 28 22:39:30 2002
@@ -172,40 +172,41 @@
 
 
 /*
- * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_0,
+ * Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END,
  * to map the target physical address. The problem is that set_fixmap()
  * provides a single page, and it is possible that the page is not
  * sufficient.
  * By using this area, we can map up to MAX_IO_APICS pages temporarily,
  * i.e. until the next __va_range() call.
+ *
+ * Important Safety Note:  The fixed I/O APIC page numbers are *subtracted*
+ * from the fixed base.  That's why we start at FIX_IO_APIC_BASE_END and
+ * count idx down while incrementing the phys address.
  */
-static __inline__ char *
+static __init char *
 __va_range(unsigned long phys, unsigned long size)
 {
-	unsigned long base, offset, mapped_size, mapped_phys = phys;
-	int idx = FIX_IO_APIC_BASE_0;
+	unsigned long base, offset, mapped_size;
+	int idx;
 
 	offset = phys & (PAGE_SIZE - 1);
 	mapped_size = PAGE_SIZE - offset;
-	set_fixmap(idx, mapped_phys);
-	base = fix_to_virt(FIX_IO_APIC_BASE_0);
+	set_fixmap(FIX_IO_APIC_BASE_END, phys);
+	base = fix_to_virt(FIX_IO_APIC_BASE_END);
+	dprintk("__va_range(0x%lx, 0x%lx): idx=%d mapped at %lx\n", phys, size,
+		FIX_IO_APIC_BASE_END, base);
 
 	/*
 	 * Most cases can be covered by the below.
 	 */
-	if (mapped_size >= size)
-		return ((unsigned char *) base + offset);
-
-	dprintk("__va_range: mapping more than a single page, size = 0x%lx\n",
-		size);
-
-	do {
-		if (idx++ == FIX_IO_APIC_BASE_END)
+	idx = FIX_IO_APIC_BASE_END;
+	while (mapped_size < size) {
+		if (--idx < FIX_IO_APIC_BASE_0)
 			return 0;	/* cannot handle this */
-		mapped_phys = mapped_phys + PAGE_SIZE;
-		set_fixmap(idx, mapped_phys);
-		mapped_size = mapped_size + PAGE_SIZE;
-	} while (mapped_size < size);
+		phys += PAGE_SIZE;
+		set_fixmap(idx, phys);
+		mapped_size += PAGE_SIZE;
+	}
 
 	return ((unsigned char *) base + offset);
 }
@@ -267,11 +268,14 @@
 	}
 
 	for (i = 0; i < tables; i++) {
-
+		/* Map in header, then map in full table length. */
 		header = (acpi_table_header *)
 			    __va_range(saved_rsdt.entry[i],
 				       sizeof(acpi_table_header));
-
+		if (!header)
+			break;
+		header = (acpi_table_header *)
+			    __va_range(saved_rsdt.entry[i], header->length);
 		if (!header)
 			break;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/i386/kernel/apic.c linux/arch/i386/kernel/apic.c
--- linux.orig/arch/i386/kernel/apic.c	Mon Feb 25 19:37:52 2002
+++ linux/arch/i386/kernel/apic.c	Tue May 28 22:39:27 2002
@@ -582,12 +582,17 @@
  * Detect and enable local APICs on non-SMP boards.
  * Original code written by Keir Fraser.
  */
+int dont_enable_local_apic __initdata = 0;
 
 static int __init detect_init_APIC (void)
 {
 	u32 h, l, features;
 	extern void get_cpu_vendor(struct cpuinfo_x86*);
 
+	/* Disabled by DMI scan or kernel option? */
+	if (dont_enable_local_apic)
+		return -1;
+
 	/* Workaround for us being called before identify_cpu(). */
 	get_cpu_vendor(&boot_cpu_data);
 
@@ -679,7 +684,15 @@
 		for (i = 0; i < nr_ioapics; i++) {
 			if (smp_found_config) {
 				ioapic_phys = mp_ioapics[i].mpc_apicaddr;
+				if (!ioapic_phys) {
+					printk(KERN_ERR "WARNING: bogus zero IO-APIC address found in MPTABLE, disabling IO/APIC support!\n");
+
+					smp_found_config = 0;
+					skip_ioapic_setup = 1;
+					goto fake_ioapic_page;
+				}
 			} else {
+fake_ioapic_page:
 				ioapic_phys = (unsigned long) alloc_bootmem_pages(PAGE_SIZE);
 				ioapic_phys = __pa(ioapic_phys);
 			}
@@ -796,8 +809,7 @@
 	 */
 
 	slice = clocks / (smp_num_cpus+1);
-	printk("cpu: %d, clocks: %d, slice: %d\n",
-		smp_processor_id(), clocks, slice);
+	printk("cpu: %d, clocks: %d, slice: %d\n", smp_processor_id(), clocks, slice);
 
 	/*
 	 * Wait for IRQ0's slice:
@@ -820,8 +832,7 @@
 
 	__setup_APIC_LVTT(clocks);
 
-	printk("CPU%d<T0:%d,T1:%d,D:%d,S:%d,C:%d>\n",
-			smp_processor_id(), t0, t1, delta, slice, clocks);
+	printk("CPU%d<T0:%d,T1:%d,D:%d,S:%d,C:%d>\n", smp_processor_id(), t0, t1, delta, slice, clocks);
 
 	__restore_flags(flags);
 }
@@ -905,8 +916,14 @@
 
 static unsigned int calibration_result;
 
+int dont_use_local_apic_timer __initdata = 0;
+
 void __init setup_APIC_clocks (void)
 {
+	/* Disabled by DMI scan or kernel option? */
+	if (dont_use_local_apic_timer)
+		return;
+
 	printk("Using local APIC timer interrupts.\n");
 	using_apic_timer = 1;
 
@@ -922,6 +939,26 @@
 
 	/* and update all other cpus */
 	smp_call_function(setup_APIC_timer, (void *)calibration_result, 1, 1);
+}
+
+void __init disable_APIC_timer(void)
+{
+	if (using_apic_timer) {
+		unsigned long v;
+
+		v = apic_read(APIC_LVTT);
+		apic_write_around(APIC_LVTT, v | APIC_LVT_MASKED);
+	}
+}
+
+void enable_APIC_timer(void)
+{
+	if (using_apic_timer) {
+		unsigned long v;
+
+		v = apic_read(APIC_LVTT);
+		apic_write_around(APIC_LVTT, v & ~APIC_LVT_MASKED);
+	}
 }
 
 /*
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/i386/kernel/apm.c linux/arch/i386/kernel/apm.c
--- linux.orig/arch/i386/kernel/apm.c	Mon Feb 25 19:37:53 2002
+++ linux/arch/i386/kernel/apm.c	Tue May 28 22:39:15 2002
@@ -275,10 +275,11 @@
  */
 
 /*
- * Define to always call the APM BIOS busy routine even if the clock was
- * not slowed by the idle routine.
+ * Define as 1 to make the driver always call the APM BIOS busy
+ * routine even if the clock was not reported as slowed by the
+ * idle routine.  Otherwise, define as 0.
  */
-#define ALWAYS_CALL_BUSY
+#define ALWAYS_CALL_BUSY   1
 
 /*
  * Define to make the APM BIOS calls zero all data segment registers (so
@@ -380,7 +381,7 @@
 static int			set_pm_idle;
 static int			suspends_pending;
 static int			standbys_pending;
-static int			waiting_for_resume;
+static int			ignore_sys_suspend;
 static int			ignore_normal_resume;
 static int			bounce_interval = DEFAULT_BOUNCE_INTERVAL;
 
@@ -470,6 +471,28 @@
 };
 #define ERROR_COUNT	(sizeof(error_table)/sizeof(lookup_t))
 
+/**
+ *	apm_error	-	display an APM error
+ *	@str: information string
+ *	@err: APM BIOS return code
+ *
+ *	Write a meaningful log entry to the kernel log in the event of
+ *	an APM error.
+ */
+ 
+static void apm_error(char *str, int err)
+{
+	int	i;
+
+	for (i = 0; i < ERROR_COUNT; i++)
+		if (error_table[i].key == err) break;
+	if (i < ERROR_COUNT)
+		printk(KERN_NOTICE "apm: %s: %s\n", str, error_table[i].msg);
+	else
+		printk(KERN_NOTICE "apm: %s: unknown error code %#2.2x\n",
+			str, err);
+}
+
 /*
  * These are the actual BIOS calls.  Depending on APM_ZERO_SEGS and
  * apm_info.allow_ints, we are being really paranoid here!  Not only
@@ -701,13 +724,13 @@
 }
 
 /**
- *	apm_set_power_state - set system wide power state
+ *	set_system_power_state - set system wide power state
  *	@state: which state to enter
  *
  *	Transition the entire system into a new APM power state.
  */
  
-static int apm_set_power_state(u_short state)
+static int set_system_power_state(u_short state)
 {
 	return set_power_state(APM_DEVICE_ALL, state);
 }
@@ -724,7 +747,6 @@
 static int apm_do_idle(void)
 {
 	u32	eax;
-	int	slowed;
 
 	if (apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &eax)) {
 		static unsigned long t;
@@ -736,13 +758,8 @@
 		}
 		return -1;
 	}
-	slowed = (apm_info.bios.flags & APM_IDLE_SLOWS_CLOCK) != 0;
-#ifdef ALWAYS_CALL_BUSY
-	clock_slowed = 1;
-#else
-	clock_slowed = slowed;
-#endif
-	return slowed;
+	clock_slowed = (apm_info.bios.flags & APM_IDLE_SLOWS_CLOCK) != 0;
+	return clock_slowed;
 }
 
 /**
@@ -755,7 +772,7 @@
 {
 	u32	dummy;
 
-	if (clock_slowed) {
+	if (clock_slowed || ALWAYS_CALL_BUSY) {
 		(void) apm_bios_call_simple(APM_FUNC_BUSY, 0, 0, &dummy);
 		clock_slowed = 0;
 	}
@@ -770,7 +787,7 @@
 #define IDLE_CALC_LIMIT   (HZ * 100)
 #define IDLE_LEAKY_MAX    16
 
-static void (*sys_idle)(void);
+static void (*original_pm_idle)(void);
 
 extern void default_idle(void);
 
@@ -784,14 +801,13 @@
 
 static void apm_cpu_idle(void)
 {
-	static int use_apm_idle = 0;
-	static unsigned int last_jiffies = 0;
-	static unsigned int last_stime = 0;
+	static int use_apm_idle; /* = 0 */
+	static unsigned int last_jiffies; /* = 0 */
+	static unsigned int last_stime; /* = 0 */
 
-	int apm_is_idle = 0;
+	int apm_idle_done = 0;
 	unsigned int jiffies_since_last_check = jiffies - last_jiffies;
-	unsigned int t1;
-
+	unsigned int bucket;
 
 recalc:
 	if (jiffies_since_last_check > IDLE_CALC_LIMIT) {
@@ -809,7 +825,7 @@
 		last_stime = current->times.tms_stime;
 	}
 
-	t1 = IDLE_LEAKY_MAX;
+	bucket = IDLE_LEAKY_MAX;
 
 	while (!current->need_resched) {
 		if (use_apm_idle) {
@@ -817,23 +833,24 @@
 
 			t = jiffies;
 			switch (apm_do_idle()) {
-			case 0: apm_is_idle = 1;
+			case 0: apm_idle_done = 1;
 				if (t != jiffies) {
-					if (t1) {
-						t1 = IDLE_LEAKY_MAX;
+					if (bucket) {
+						bucket = IDLE_LEAKY_MAX;
 						continue;
 					}
-				} else if (t1) {
-					t1--;
+				} else if (bucket) {
+					bucket--;
 					continue;
 				}
 				break;
-			case 1: apm_is_idle = 1;
+			case 1: apm_idle_done = 1;
 				break;
+			default: /* BIOS refused */
 			}
 		}
-		if (sys_idle)
-			sys_idle();
+		if (original_pm_idle)
+			original_pm_idle();
 		else
 			default_idle();
 		jiffies_since_last_check = jiffies - last_jiffies;
@@ -841,7 +858,7 @@
 			goto recalc;
 	}
 
-	if (apm_is_idle)
+	if (apm_idle_done)
 		apm_do_busy();
 }
 
@@ -889,7 +906,7 @@
 	if (apm_info.realmode_power_off)
 		machine_real_restart(po_bios_call, sizeof(po_bios_call));
 	else
-		(void) apm_set_power_state(APM_STATE_OFF);
+		(void) set_system_power_state(APM_STATE_OFF);
 }
 
 /**
@@ -1034,28 +1051,6 @@
 	return APM_SUCCESS;
 }
 
-/**
- *	apm_error	-	display an APM error
- *	@str: information string
- *	@err: APM BIOS return code
- *
- *	Write a meaningful log entry to the kernel log in the event of
- *	an APM error.
- */
- 
-static void apm_error(char *str, int err)
-{
-	int	i;
-
-	for (i = 0; i < ERROR_COUNT; i++)
-		if (error_table[i].key == err) break;
-	if (i < ERROR_COUNT)
-		printk(KERN_NOTICE "apm: %s: %s\n", str, error_table[i].msg);
-	else
-		printk(KERN_NOTICE "apm: %s: unknown error code %#2.2x\n",
-			str, err);
-}
-
 #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
 
 /**
@@ -1194,9 +1189,9 @@
 		/* Vetoed */
 		if (vetoable) {
 			if (apm_info.connection_version > 0x100)
-				apm_set_power_state(APM_STATE_REJECT);
+				set_system_power_state(APM_STATE_REJECT);
 			err = -EBUSY;
-			waiting_for_resume = 0;
+			ignore_sys_suspend = 0;
 			printk(KERN_WARNING "apm: suspend was vetoed.\n");
 			goto out;
 		}
@@ -1204,9 +1199,10 @@
 	}
 	get_time_diff();
 	cli();
-	err = apm_set_power_state(APM_STATE_SUSPEND);
+	err = set_system_power_state(APM_STATE_SUSPEND);
 	reinit_timer();
 	set_time();
+	ignore_normal_resume = 1;
 	sti();
 	if (err == APM_NO_ERROR)
 		err = APM_SUCCESS;
@@ -1215,7 +1211,6 @@
 	err = (err == APM_SUCCESS) ? 0 : -EIO;
 	pm_send_all(PM_RESUME, (void *)0);
 	queue_event(APM_NORMAL_RESUME, NULL);
-	ignore_normal_resume = 1;
  out:
 	for (as = user_list; as != NULL; as = as->next) {
 		as->suspend_wait = 0;
@@ -1231,7 +1226,7 @@
 
 	/* If needed, notify drivers here */
 	get_time_diff();
-	err = apm_set_power_state(APM_STATE_STANDBY);
+	err = set_system_power_state(APM_STATE_STANDBY);
 	if ((err != APM_SUCCESS) && (err != APM_NO_ERROR))
 		apm_error("standby", err);
 }
@@ -1285,13 +1280,13 @@
 		case APM_USER_SUSPEND:
 #ifdef CONFIG_APM_IGNORE_USER_SUSPEND
 			if (apm_info.connection_version > 0x100)
-				apm_set_power_state(APM_STATE_REJECT);
+				set_system_power_state(APM_STATE_REJECT);
 			break;
 #endif
 		case APM_SYS_SUSPEND:
 			if (ignore_bounce) {
 				if (apm_info.connection_version > 0x100)
-					apm_set_power_state(APM_STATE_REJECT);
+					set_system_power_state(APM_STATE_REJECT);
 				break;
 			}
 			/*
@@ -1302,9 +1297,9 @@
 			 * sending a SUSPEND event until something else
 			 * happens!
 			 */
-			if (waiting_for_resume)
+			if (ignore_sys_suspend)
 				return;
-			waiting_for_resume = 1;
+			ignore_sys_suspend = 1;
 			queue_event(event, NULL);
 			if (suspends_pending <= 0)
 				(void) suspend(1);
@@ -1313,7 +1308,7 @@
 		case APM_NORMAL_RESUME:
 		case APM_CRITICAL_RESUME:
 		case APM_STANDBY_RESUME:
-			waiting_for_resume = 0;
+			ignore_sys_suspend = 0;
 			last_resume = jiffies;
 			ignore_bounce = 1;
 			if ((event != APM_NORMAL_RESUME)
@@ -1357,7 +1352,7 @@
 			pending_count = 4;
 			if (debug)
 				printk(KERN_DEBUG "apm: setting state busy\n");
-			err = apm_set_power_state(APM_STATE_BUSY);
+			err = set_system_power_state(APM_STATE_BUSY);
 			if (err)
 				apm_error("busy", err);
 		}
@@ -1964,7 +1959,7 @@
 	if (HZ != 100)
 		idle_period = (idle_period * HZ) / 100;
 	if (idle_threshold < 100) {
-		sys_idle = pm_idle;
+		original_pm_idle = pm_idle;
 		pm_idle  = apm_cpu_idle;
 		set_pm_idle = 1;
 	}
@@ -1977,7 +1972,7 @@
 	int	error;
 
 	if (set_pm_idle)
-		pm_idle = sys_idle;
+		pm_idle = original_pm_idle;
 	if (((apm_info.bios.flags & APM_BIOS_DISENGAGED) == 0)
 	    && (apm_info.connection_version > 0x0100)) {
 		error = apm_engage_power_management(APM_DEVICE_ALL, 0);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/i386/kernel/bluesmoke.c linux/arch/i386/kernel/bluesmoke.c
--- linux.orig/arch/i386/kernel/bluesmoke.c	Mon Nov 12 17:59:43 2001
+++ linux/arch/i386/kernel/bluesmoke.c	Tue May 28 22:39:23 2002
@@ -3,9 +3,12 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/config.h>
 #include <asm/processor.h> 
 #include <asm/msr.h>
 
+#ifdef CONFIG_X86_MCE
+
 static int mce_disabled __initdata = 0;
 
 /*
@@ -41,13 +44,12 @@
 			if(high&(1<<27))
 			{
 				rdmsr(MSR_IA32_MC0_MISC+i*4, alow, ahigh);
-				printk("[%08x%08x]", alow, ahigh);
+				printk("[%08x%08x]", ahigh, alow);
 			}
 			if(high&(1<<26))
 			{
 				rdmsr(MSR_IA32_MC0_ADDR+i*4, alow, ahigh);
-				printk(" at %08x%08x", 
-					high, low);
+				printk(" at %08x%08x", ahigh, alow);
 			}
 			printk("\n");
 			/* Clear it */
@@ -247,3 +249,8 @@
 
 __setup("nomce", mcheck_disable);
 __setup("mce", mcheck_enable);
+
+#else
+asmlinkage void do_machine_check(struct pt_regs * regs, long error_code) {}
+void __init mcheck_init(struct cpuinfo_x86 *c) {}
+#endif
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/i386/kernel/dmi_scan.c linux/arch/i386/kernel/dmi_scan.c
--- linux.orig/arch/i386/kernel/dmi_scan.c	Mon Feb 25 19:37:53 2002
+++ linux/arch/i386/kernel/dmi_scan.c	Tue May 28 22:39:24 2002
@@ -9,6 +9,7 @@
 #include <linux/pm.h>
 #include <asm/keyboard.h>
 #include <asm/system.h>
+#include <linux/bootmem.h>
 
 unsigned long dmi_broken;
 int is_sony_vaio_laptop;
@@ -51,7 +52,7 @@
 	u8 *data;
 	int i=1;
 		
-	buf = ioremap(base, len);
+	buf = bt_ioremap(base, len);
 	if(buf==NULL)
 		return -1;
 
@@ -83,7 +84,7 @@
 		data+=2;
 		i++;
 	}
-	iounmap(buf);
+	bt_iounmap(buf, len);
 	return 0;
 }
 
@@ -155,7 +156,7 @@
 		return;
 	if (dmi_ident[slot])
 		return;
-	dmi_ident[slot] = kmalloc(strlen(p)+1, GFP_KERNEL);
+	dmi_ident[slot] = alloc_bootmem(strlen(p)+1);
 	if(dmi_ident[slot])
 		strcpy(dmi_ident[slot], p);
 	else
@@ -292,6 +293,62 @@
 	return 0;
 }
 
+/*
+ * Some machines, usually laptops, can't handle an enabled local APIC.
+ * The symptoms include hangs or reboots when suspending or resuming,
+ * attaching or detaching the power cord, or entering BIOS setup screens
+ * through magic key sequences.
+ */
+static int __init local_apic_kills_bios(struct dmi_blacklist *d)
+{
+#ifdef CONFIG_X86_LOCAL_APIC
+	extern int dont_enable_local_apic;
+	if (!dont_enable_local_apic) {
+		dont_enable_local_apic = 1;
+		printk(KERN_WARNING "%s with broken BIOS detected. "
+		       "Refusing to enable the local APIC.\n",
+		       d->ident);
+	}
+#endif
+	return 0;
+}
+
+/*
+ * The Microstar 6163-2 (a.k.a Pro) mainboard will hang shortly after
+ * resumes, and also at what appears to be asynchronous APM events,
+ * if the local APIC is enabled.
+ */
+static int __init apm_kills_local_apic(struct dmi_blacklist *d)
+{
+#ifdef CONFIG_X86_LOCAL_APIC
+	extern int dont_enable_local_apic;
+	if (apm_info.bios.version && !dont_enable_local_apic) {
+		dont_enable_local_apic = 1;
+		printk(KERN_WARNING "%s with broken BIOS detected. "
+		       "Refusing to enable the local APIC.\n",
+		       d->ident);
+	}
+#endif
+	return 0;
+}
+
+/*
+ * The Intel AL440LX mainboard will hang randomly if the local APIC
+ * timer is running and the APM BIOS hasn't been disabled.
+ */
+static int __init apm_kills_local_apic_timer(struct dmi_blacklist *d)
+{
+#ifdef CONFIG_X86_LOCAL_APIC
+	extern int dont_use_local_apic_timer;
+	if (apm_info.bios.version && !dont_use_local_apic_timer) {
+		dont_use_local_apic_timer = 1;
+		printk(KERN_WARNING "%s with broken BIOS detected. "
+		       "The local APIC timer will not be used.\n",
+		       d->ident);
+	}
+#endif
+	return 0;
+}
 
 /*
  *  Check for clue free BIOS implementations who use
@@ -353,6 +410,7 @@
  * The MP1.4 table is right however and so SMP kernels tend to work. 
  */
  
+extern int skip_ioapic_setup;
 static __init int broken_pirq(struct dmi_blacklist *d)
 {
 	printk(KERN_INFO " *** Possibly defective BIOS detected (irqtable)\n");
@@ -360,6 +418,9 @@
 	printk(KERN_INFO " *** If you see IRQ problems, in paticular SCSI resets and hangs at boot\n");
 	printk(KERN_INFO " *** contact your hardware vendor and ask about updates.\n");
 	printk(KERN_INFO " *** Building an SMP kernel may evade the bug some of the time.\n");
+#ifdef CONFIG_X86_IO_APIC
+	skip_ioapic_setup = 0;
+#endif
 	return 0;
 }
 
@@ -452,6 +513,11 @@
 			MATCH(DMI_BIOS_VERSION, "A04"),
 			MATCH(DMI_BIOS_DATE, "08/24/2000"), NO_MATCH
 			} },
+	{ broken_apm_power, "Dell Inspiron 2500", {	/* Handle problems with APM on Inspiron 2500 */
+			MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
+			MATCH(DMI_BIOS_VERSION, "A12"),
+			MATCH(DMI_BIOS_DATE, "02/04/2002"), 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"),
@@ -493,12 +559,23 @@
 			MATCH(DMI_PRODUCT_NAME, "Delhi3"),
 			NO_MATCH, NO_MATCH,
 			} },
+	{ apm_is_horked, "Fujitsu-Siemens", { /* APM crashes */
+			MATCH(DMI_BIOS_VENDOR, "hoenix/FUJITSU SIEMENS"),
+			MATCH(DMI_BIOS_VERSION, "Version1.01"),
+			NO_MATCH, NO_MATCH,
+			} },
 	{ apm_is_horked, "Sharp PC-PJ/AX", { /* APM crashes */
 			MATCH(DMI_SYS_VENDOR, "SHARP"),
 			MATCH(DMI_PRODUCT_NAME, "PC-PJ/AX"),
 			MATCH(DMI_BIOS_VENDOR,"SystemSoft"),
 			MATCH(DMI_BIOS_VERSION,"Version R2.08")
 			} },
+	{ apm_is_horked, "Dell Inspiron 2500", { /* APM crashes */
+			MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
+			MATCH(DMI_PRODUCT_NAME, "Inspiron 2500"),
+			MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
+			MATCH(DMI_BIOS_VERSION,"A11")
+			} },
 	{ sony_vaio_laptop, "Sony Vaio", { /* This is a Sony Vaio laptop */
 			MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
 			MATCH(DMI_PRODUCT_NAME, "PCG-"),
@@ -534,6 +611,12 @@
 			MATCH(DMI_BIOS_DATE, "08/11/00"), NO_MATCH
 			} },
 
+	{ swab_apm_power_in_minutes, "Sony VAIO", {	/* Handle problems with APM on Sony Vaio PCG-Z600LEK(DE) */
+			MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
+			MATCH(DMI_BIOS_VERSION, "R0206Z3"),
+			MATCH(DMI_BIOS_DATE, "12/25/00"), NO_MATCH
+			} },
+
 	{ swab_apm_power_in_minutes, "Sony VAIO", {	/* Handle problems with APM on Sony Vaio PCG-Z505LS */
 			MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
 			MATCH(DMI_BIOS_VERSION, "R0203D0"),
@@ -546,6 +629,12 @@
 			MATCH(DMI_BIOS_DATE, "08/25/00"), NO_MATCH
 			} },
 	
+	{ swab_apm_power_in_minutes, "Sony VAIO", {	/* Handle problems with APM on Sony Vaio PCG-Z505LS (with updated BIOS) */
+			MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
+			MATCH(DMI_BIOS_VERSION, "R0209Z3"),
+			MATCH(DMI_BIOS_DATE, "05/12/01"), NO_MATCH
+			} },
+	
 	{ swab_apm_power_in_minutes, "Sony VAIO", {	/* Handle problems with APM on Sony Vaio PCG-F104K */
 			MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
 			MATCH(DMI_BIOS_VERSION, "R0204K2"),
@@ -563,6 +652,36 @@
 			MATCH(DMI_BIOS_DATE, "09/12/00"), NO_MATCH
 			} },
 
+	/* Machines which have problems handling enabled local APICs */
+
+	{ local_apic_kills_bios, "Dell Inspiron", {
+			MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
+			MATCH(DMI_PRODUCT_NAME, "Inspiron"),
+			NO_MATCH, NO_MATCH
+			} },
+
+	{ local_apic_kills_bios, "Dell Latitude", {
+			MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
+			MATCH(DMI_PRODUCT_NAME, "Latitude"),
+			NO_MATCH, NO_MATCH
+			} },
+
+	{ local_apic_kills_bios, "IBM Thinkpad T20", {
+			MATCH(DMI_BOARD_VENDOR, "IBM"),
+			MATCH(DMI_BOARD_NAME, "264741U"),
+			NO_MATCH, NO_MATCH
+			} },
+
+	{ apm_kills_local_apic, "Microstar 6163", {
+			MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
+			MATCH(DMI_BOARD_NAME, "MS-6163"),
+			NO_MATCH, NO_MATCH } },
+
+	{ apm_kills_local_apic_timer, "Intel AL440LX", {
+			MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
+			MATCH(DMI_BOARD_NAME, "AL440LX"),
+			NO_MATCH, NO_MATCH } },
+
 	/* Problem Intel 440GX bioses */
 
 	{ broken_pirq, "SABR1 Bios", {			/* Bad $PIR */
@@ -731,12 +850,9 @@
 	}
 }
 
-static int __init dmi_scan_machine(void)
+void __init dmi_scan_machine(void)
 {
 	int err = dmi_iterate(dmi_decode);
 	if(err == 0)
 		dmi_check_blacklist();
-	return err;
 }
-
-module_init(dmi_scan_machine);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S
--- linux.orig/arch/i386/kernel/entry.S	Mon Feb 25 19:37:53 2002
+++ linux/arch/i386/kernel/entry.S	Tue May 28 22:39:21 2002
@@ -634,6 +634,11 @@
 	.long SYMBOL_NAME(sys_ni_syscall)	/* 235 reserved for removexattr */
 	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for lremovexattr */
 	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for fremovexattr */
+ 	.long SYMBOL_NAME(sys_tkill)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for sendfile64 */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* 240 reserved for futex */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for sched_setaffinity */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for sched_getaffinity */
 
 	.rept NR_syscalls-(.-sys_call_table)/4
 		.long SYMBOL_NAME(sys_ni_syscall)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/i386/kernel/head.S linux/arch/i386/kernel/head.S
--- linux.orig/arch/i386/kernel/head.S	Mon Feb 25 19:37:53 2002
+++ linux/arch/i386/kernel/head.S	Tue May 28 22:39:16 2002
@@ -178,7 +178,7 @@
  * we don't need to preserve eflags.
  */
 
-	movl $3,X86		# at least 386
+	movb $3,X86		# at least 386
 	pushfl			# push EFLAGS
 	popl %eax		# get EFLAGS
 	movl %eax,%ecx		# save original EFLAGS
@@ -191,7 +191,7 @@
 	andl $0x40000,%eax	# check if AC bit changed
 	je is386
 
-	movl $4,X86		# at least 486
+	movb $4,X86		# at least 486
 	movl %ecx,%eax
 	xorl $0x200000,%eax	# check ID flag
 	pushl %eax
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/i386/kernel/i386_ksyms.c linux/arch/i386/kernel/i386_ksyms.c
--- linux.orig/arch/i386/kernel/i386_ksyms.c	Mon Feb 25 19:37:53 2002
+++ linux/arch/i386/kernel/i386_ksyms.c	Tue May 28 22:39:27 2002
@@ -73,6 +73,7 @@
 EXPORT_SYMBOL(get_cmos_time);
 EXPORT_SYMBOL(apm_info);
 EXPORT_SYMBOL(gdt);
+EXPORT_SYMBOL(empty_zero_page);
 
 #ifdef CONFIG_DEBUG_IOVIRT
 EXPORT_SYMBOL(__io_virt_debug);
@@ -126,7 +127,7 @@
 
 #ifdef CONFIG_SMP
 EXPORT_SYMBOL(cpu_data);
-EXPORT_SYMBOL(kernel_flag);
+EXPORT_SYMBOL(kernel_flag_cacheline);
 EXPORT_SYMBOL(smp_num_cpus);
 EXPORT_SYMBOL(cpu_online_map);
 EXPORT_SYMBOL_NOVERS(__write_lock_failed);
@@ -145,6 +146,10 @@
 EXPORT_SYMBOL(flush_tlb_page);
 #endif
 
+#ifdef CONFIG_X86_IO_APIC
+EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector);
+#endif
+
 #ifdef CONFIG_MCA
 EXPORT_SYMBOL(machine_id);
 #endif
@@ -166,10 +171,6 @@
 
 #ifdef CONFIG_HAVE_DEC_LOCK
 EXPORT_SYMBOL(atomic_dec_and_lock);
-#endif
-
-#ifdef CONFIG_DEBUG_BUGVERBOSE
-EXPORT_SYMBOL(do_BUG);
 #endif
 
 extern int is_sony_vaio_laptop;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/i386/kernel/io_apic.c linux/arch/i386/kernel/io_apic.c
--- linux.orig/arch/i386/kernel/io_apic.c	Wed Nov 14 01:28:41 2001
+++ linux/arch/i386/kernel/io_apic.c	Tue May 28 22:39:23 2002
@@ -67,7 +67,7 @@
  * shared ISA-space IRQs, so we have to support them. We are super
  * fast in the common case, and fast for shared ISA-space IRQs.
  */
-static void add_pin_to_irq(unsigned int irq, int apic, int pin)
+static void __init add_pin_to_irq(unsigned int irq, int apic, int pin)
 {
 	static int first_free_entry = NR_IRQS;
 	struct irq_pin_list *entry = irq_2_pin + irq;
@@ -85,6 +85,26 @@
 	entry->pin = pin;
 }
 
+/*
+ * Reroute an IRQ to a different pin.
+ */
+static void __init replace_pin_at_irq(unsigned int irq,
+				      int oldapic, int oldpin,
+				      int newapic, int newpin)
+{
+	struct irq_pin_list *entry = irq_2_pin + irq;
+
+	while (1) {
+		if (entry->apic == oldapic && entry->pin == oldpin) {
+			entry->apic = newapic;
+			entry->pin = newpin;
+		}
+		if (!entry->next)
+			break;
+		entry = irq_2_pin + entry->next;
+	}
+}
+
 #define __DO_ACTION(R, ACTION, FINAL)					\
 									\
 {									\
@@ -173,13 +193,21 @@
 int pirqs_enabled;
 int skip_ioapic_setup;
 
-static int __init ioapic_setup(char *str)
+static int __init noioapic_setup(char *str)
 {
 	skip_ioapic_setup = 1;
 	return 1;
 }
 
-__setup("noapic", ioapic_setup);
+__setup("noapic", noioapic_setup);
+
+static int __init ioapic_setup(char *str)
+{
+	skip_ioapic_setup = 0;
+	return 1;
+}
+
+__setup("apic", ioapic_setup);
 
 static int __init ioapic_pirq_setup(char *str)
 {
@@ -622,7 +650,14 @@
 		}
 
 		irq = pin_2_irq(idx, apic, pin);
-		add_pin_to_irq(irq, apic, pin);
+		/*
+		 * skip adding the timer int on secondary nodes, which causes
+		 * a small but painful rift in the time-space continuum
+		 */
+		if (clustered_apic_mode && (apic != 0) && (irq == 0))
+			continue;
+		else
+			add_pin_to_irq(irq, apic, pin);
 
 		if (!apic && !IO_APIC_IRQ(irq))
 			continue;
@@ -1533,6 +1568,10 @@
 		setup_ExtINT_IRQ0_pin(pin2, vector);
 		if (timer_irq_works()) {
 			printk("works.\n");
+			if (pin1 != -1)
+				replace_pin_at_irq(0, 0, pin1, 0, pin2);
+			else
+				add_pin_to_irq(0, 0, pin2);
 			if (nmi_watchdog == NMI_IO_APIC) {
 				setup_nmi();
 				check_nmi_watchdog();
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/i386/kernel/microcode.c linux/arch/i386/kernel/microcode.c
--- linux.orig/arch/i386/kernel/microcode.c	Tue Oct 30 23:13:17 2001
+++ linux/arch/i386/kernel/microcode.c	Tue May 28 22:39:19 2002
@@ -51,6 +51,12 @@
  *		Bugfix for HT (Hyper-Threading) enabled processors
  *		whereby processor resources are shared by all logical processors
  *		in a single CPU package.
+ *	1.10	28 Feb 2002 Asit K Mallick <asit.k.mallick@intel.com> and
+ *		Tigran Aivazian <tigran@veritas.com>,
+ *		Serialize updates as required on HT processors due to speculative
+ *		nature of implementation.
+ *	1.11	22 Mar 2001 Tigran Aivazian <tigran@veritas.com>
+ *		Fix the panic when writing zero-length microcode chunk.
  */
 
 #include <linux/init.h>
@@ -60,12 +66,16 @@
 #include <linux/vmalloc.h>
 #include <linux/miscdevice.h>
 #include <linux/devfs_fs_kernel.h>
+#include <linux/spinlock.h>
 
 #include <asm/msr.h>
 #include <asm/uaccess.h>
 #include <asm/processor.h>
 
-#define MICROCODE_VERSION 	"1.09"
+
+static spinlock_t microcode_update_lock = SPIN_LOCK_UNLOCKED;
+
+#define MICROCODE_VERSION 	"1.11"
 
 MODULE_DESCRIPTION("Intel CPU (IA-32) microcode update driver");
 MODULE_AUTHOR("Tigran Aivazian <tigran@veritas.com>");
@@ -195,7 +205,8 @@
 	struct cpuinfo_x86 *c = cpu_data + cpu_num;
 	struct update_req *req = update_req + cpu_num;
 	unsigned int pf = 0, val[2], rev, sig;
-	int i,found=0;
+	unsigned long flags;
+	int i;
 
 	req->err = 1; /* assume update will fail on this cpu */
 
@@ -216,8 +227,9 @@
 	for (i=0; i<microcode_num; i++)
 		if (microcode[i].sig == sig && microcode[i].pf == pf &&
 		    microcode[i].ldrver == 1 && microcode[i].hdrver == 1) {
-
-			found=1;
+			int sum = 0;
+			struct microcode *m = &microcode[i];
+			unsigned int *sump = (unsigned int *)(m+1);
 
 			printf("Microcode\n");
 			printf("   Header Revision %d\n",microcode[i].hdrver);
@@ -234,54 +246,69 @@
 			printf("   Loader Revision %x\n",microcode[i].ldrver);
 			printf("   Processor Flags %x\n\n",microcode[i].pf);
 
+			req->slot = i;
+
+			/* serialize access to update decision */
+			spin_lock_irqsave(&microcode_update_lock, flags);          
+
 			/* trick, to work even if there was no prior update by the BIOS */
 			wrmsr(MSR_IA32_UCODE_REV, 0, 0);
 			__asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", "dx");
 
 			/* get current (on-cpu) revision into rev (ignore val[0]) */
 			rdmsr(MSR_IA32_UCODE_REV, val[0], rev);
+			
 			if (microcode[i].rev < rev) {
+				spin_unlock_irqrestore(&microcode_update_lock, flags);
 				printk(KERN_ERR 
-					"microcode: CPU%d not 'upgrading' to earlier revision"
+				       "microcode: CPU%d not 'upgrading' to earlier revision"
+				       " %d (current=%d)\n", cpu_num, microcode[i].rev, rev);
+				return;
+			} else if (microcode[i].rev == rev) {
+				/* notify the caller of success on this cpu */
+				req->err = 0;
+				spin_unlock_irqrestore(&microcode_update_lock, flags);
+				printk(KERN_ERR 
+					"microcode: CPU%d already at revision"
 					" %d (current=%d)\n", cpu_num, microcode[i].rev, rev);
-			} else {
-				int sum = 0;
-				struct microcode *m = &microcode[i];
-				unsigned int *sump = (unsigned int *)(m+1);
-
-				while (--sump >= (unsigned int *)m)
-					sum += *sump;
-				if (sum != 0) {
-					printk(KERN_ERR "microcode: CPU%d aborting, "
-							"bad checksum\n", cpu_num);
-					break;
-				}
-
-				/* write microcode via MSR 0x79 */
-				wrmsr(MSR_IA32_UCODE_WRITE, (unsigned int)(m->bits), 0);
+				return;
+			}
 
-				/* serialize */
-				__asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", "dx");
+			/* Verify the checksum */
+			while (--sump >= (unsigned int *)m)
+				sum += *sump;
+			if (sum != 0) {
+				req->err = 1;
+				spin_unlock_irqrestore(&microcode_update_lock, flags);
+				printk(KERN_ERR "microcode: CPU%d aborting, "
+				       "bad checksum\n", cpu_num);
+				return;
+			}
+			
+			/* write microcode via MSR 0x79 */
+			wrmsr(MSR_IA32_UCODE_WRITE, (unsigned int)(m->bits), 0);
 
-				/* get the current revision from MSR 0x8B */
-				rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);
+			/* serialize */
+			__asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", "dx");
 
-				/* notify the caller of success on this cpu */
-				req->err = 0;
-				req->slot = i;
+			/* get the current revision from MSR 0x8B */
+			rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);
 
-				printk(KERN_INFO "microcode: CPU%d updated from revision "
-						"%d to %d, date=%08x\n", 
-						cpu_num, rev, val[1], m->date);
-			}
-			break;
+			/* notify the caller of success on this cpu */
+			req->err = 0;
+			spin_unlock_irqrestore(&microcode_update_lock, flags);
+			printk(KERN_INFO "microcode: CPU%d updated from revision "
+			       "%d to %d, date=%08x\n", 
+			       cpu_num, rev, val[1], microcode[i].date);
+			return;
 		}
-
-	if(!found)
-		printk(KERN_ERR "microcode: CPU%d no microcode found! (sig=%x, pflags=%d)\n",
-				cpu_num, sig, pf);
+	
+	printk(KERN_ERR
+	       "microcode: CPU%d no microcode found! (sig=%x, pflags=%d)\n", 
+	       cpu_num, sig, pf);
 }
 
+
 static ssize_t microcode_read(struct file *file, char *buf, size_t len, loff_t *ppos)
 {
 	ssize_t ret = 0;
@@ -305,9 +332,13 @@
 {
 	ssize_t ret;
 
-	if (len % sizeof(struct microcode) != 0) {
+	if (!len || len % sizeof(struct microcode) != 0) {
 		printk(KERN_ERR "microcode: can only write in N*%d bytes units\n", 
 			sizeof(struct microcode));
+		return -EINVAL;
+	}
+	if ((len >> PAGE_SHIFT) > num_physpages) {
+		printk(KERN_ERR "microcode: too much data (max %ld pages)\n", num_physpages);
 		return -EINVAL;
 	}
 	down_write(&microcode_rwsem);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/i386/kernel/mpparse.c linux/arch/i386/kernel/mpparse.c
--- linux.orig/arch/i386/kernel/mpparse.c	Fri Nov  9 22:58:18 2001
+++ linux/arch/i386/kernel/mpparse.c	Tue May 28 22:39:22 2002
@@ -37,6 +37,8 @@
 int apic_version [MAX_APICS];
 int mp_bus_id_to_type [MAX_MP_BUSSES];
 int mp_bus_id_to_node [MAX_MP_BUSSES];
+int mp_bus_id_to_local [MAX_MP_BUSSES];
+int quad_local_to_mp_bus_id [NR_CPUS/4][4];
 int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 };
 int mp_current_pci_id;
 
@@ -241,13 +243,17 @@
 static void __init MP_bus_info (struct mpc_config_bus *m)
 {
 	char str[7];
+	int quad;
 
 	memcpy(str, m->mpc_bustype, 6);
 	str[6] = 0;
 	
 	if (clustered_apic_mode) {
-		mp_bus_id_to_node[m->mpc_busid] = translation_table[mpc_record]->trans_quad;
-		printk("Bus #%d is %s (node %d)\n", m->mpc_busid, str, mp_bus_id_to_node[m->mpc_busid]);
+		quad = translation_table[mpc_record]->trans_quad;
+		mp_bus_id_to_node[m->mpc_busid] = quad;
+		mp_bus_id_to_local[m->mpc_busid] = translation_table[mpc_record]->trans_local;
+		quad_local_to_mp_bus_id[quad][translation_table[mpc_record]->trans_local] = m->mpc_busid;
+		printk("Bus #%d is %s (node %d)\n", m->mpc_busid, str, quad);
 	} else {
 		Dprintk("Bus #%d is %s\n", m->mpc_busid, str);
 	}
@@ -324,13 +330,14 @@
 
 static void __init MP_translation_info (struct mpc_config_translation *m)
 {
-	printk("Translation: record %d, type %d, quad %d, global %d, local %d\n", mpc_record, m->trans_type, 
-		m->trans_quad, m->trans_global, m->trans_local);
+	printk("Translation: record %d, type %d, quad %d, global %d, local %d\n", mpc_record, m->trans_type, m->trans_quad, m->trans_global, m->trans_local);
 
 	if (mpc_record >= MAX_MPC_ENTRY) 
 		printk("MAX_MPC_ENTRY exceeded!\n");
 	else
 		translation_table[mpc_record] = m; /* stash this for later */
+	if (m->trans_quad+1 > numnodes)
+		numnodes = m->trans_quad+1;
 }
 
 /*
@@ -494,10 +501,6 @@
 			}
 		}
 		++mpc_record;
-	}
-	if (clustered_apic_mode && nr_ioapics > 2) {
-		/* don't initialise IO apics on secondary quads */
-		nr_ioapics = 2;
 	}
 	if (!num_processors)
 		printk(KERN_ERR "SMP mptable: no processors registered!\n");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/i386/kernel/mtrr.c linux/arch/i386/kernel/mtrr.c
--- linux.orig/arch/i386/kernel/mtrr.c	Fri Nov  9 21:58:02 2001
+++ linux/arch/i386/kernel/mtrr.c	Tue May 28 22:39:14 2002
@@ -378,10 +378,8 @@
 static int arr3_protected;
 
 /*  Put the processor into a state where MTRRs can be safely set  */
-static void set_mtrr_prepare (struct set_mtrr_context *ctxt)
+static void set_mtrr_prepare_save (struct set_mtrr_context *ctxt)
 {
-    unsigned long tmp;
-
     /*  Disable interrupts locally  */
     __save_flags (ctxt->flags); __cli ();
 
@@ -404,16 +402,27 @@
     }
 
     if ( mtrr_if == MTRR_IF_INTEL ) {
-	/*  Disable MTRRs, and set the default type to uncached  */
+	/*  Save MTRR state */
 	rdmsr (MTRRdefType_MSR, ctxt->deftype_lo, ctxt->deftype_hi);
+    } else {
+	/* Cyrix ARRs - everything else were excluded at the top */
+	ctxt->ccr3 = getCx86 (CX86_CCR3);
+    }
+}   /*  End Function set_mtrr_prepare_save  */
+
+static void set_mtrr_disable (struct set_mtrr_context *ctxt)
+{
+    if ( mtrr_if != MTRR_IF_INTEL && mtrr_if != MTRR_IF_CYRIX_ARR )
+	 return;
+
+    if ( mtrr_if == MTRR_IF_INTEL ) {
+	/*  Disable MTRRs, and set the default type to uncached  */
 	wrmsr (MTRRdefType_MSR, ctxt->deftype_lo & 0xf300UL, ctxt->deftype_hi);
     } else {
 	/* Cyrix ARRs - everything else were excluded at the top */
-	tmp = getCx86 (CX86_CCR3);
-	setCx86 (CX86_CCR3, (tmp & 0x0f) | 0x10);
-	ctxt->ccr3 = tmp;
+	setCx86 (CX86_CCR3, (ctxt->ccr3 & 0x0f) | 0x10);
     }
-}   /*  End Function set_mtrr_prepare  */
+}   /*  End Function set_mtrr_disable  */
 
 /*  Restore the processor after a set_mtrr_prepare  */
 static void set_mtrr_done (struct set_mtrr_context *ctxt)
@@ -674,7 +683,10 @@
 {
     struct set_mtrr_context ctxt;
 
-    if (do_safe) set_mtrr_prepare (&ctxt);
+    if (do_safe) {
+	set_mtrr_prepare_save (&ctxt);
+	set_mtrr_disable (&ctxt);
+	}
     if (size == 0)
     {
 	/* The invalid bit is kept in the mask, so we simply clear the
@@ -726,7 +738,10 @@
 	}
     }
 
-    if (do_safe) set_mtrr_prepare (&ctxt);
+    if (do_safe) {
+	set_mtrr_prepare_save (&ctxt);
+	set_mtrr_disable (&ctxt);
+    }
     base <<= PAGE_SHIFT;
     setCx86(arr,    ((unsigned char *) &base)[3]);
     setCx86(arr+1,  ((unsigned char *) &base)[2]);
@@ -750,7 +765,10 @@
     u32 regs[2];
     struct set_mtrr_context ctxt;
 
-    if (do_safe) set_mtrr_prepare (&ctxt);
+    if (do_safe) {
+	set_mtrr_prepare_save (&ctxt);
+	set_mtrr_disable (&ctxt);
+    }
     /*
      *	Low is MTRR0 , High MTRR 1
      */
@@ -788,7 +806,10 @@
     struct set_mtrr_context ctxt;
     unsigned long low, high;
 
-    if (do_safe) set_mtrr_prepare( &ctxt );
+    if (do_safe) {
+	set_mtrr_prepare_save (&ctxt);
+	set_mtrr_disable (&ctxt);
+    }
     if (size == 0)
     {
         /*  Disable  */
@@ -985,6 +1006,7 @@
 
 
 static atomic_t undone_count;
+static volatile int wait_barrier_mtrr_disable = FALSE;
 static volatile int wait_barrier_execute = FALSE;
 static volatile int wait_barrier_cache_enable = FALSE;
 
@@ -1003,18 +1025,21 @@
 {
     struct set_mtrr_data *data = info;
     struct set_mtrr_context ctxt;
-
-    set_mtrr_prepare (&ctxt);
+    set_mtrr_prepare_save (&ctxt);
     /*  Notify master that I've flushed and disabled my cache  */
     atomic_dec (&undone_count);
-    while (wait_barrier_execute) barrier ();
+    while (wait_barrier_mtrr_disable) { rep_nop(); barrier(); }
+    set_mtrr_disable (&ctxt);
+    /*  Notify master that I've flushed and disabled my cache  */
+    atomic_dec (&undone_count);
+    while (wait_barrier_execute) { rep_nop(); barrier(); }
     /*  The master has cleared me to execute  */
     (*set_mtrr_up) (data->smp_reg, data->smp_base, data->smp_size,
 		    data->smp_type, FALSE);
     /*  Notify master CPU that I've executed the function  */
     atomic_dec (&undone_count);
     /*  Wait for master to clear me to enable cache and return  */
-    while (wait_barrier_cache_enable) barrier ();
+    while (wait_barrier_cache_enable) { rep_nop(); barrier(); }
     set_mtrr_done (&ctxt);
 }   /*  End Function ipi_handler  */
 
@@ -1028,6 +1053,7 @@
     data.smp_base = base;
     data.smp_size = size;
     data.smp_type = type;
+    wait_barrier_mtrr_disable = TRUE;
     wait_barrier_execute = TRUE;
     wait_barrier_cache_enable = TRUE;
     atomic_set (&undone_count, smp_num_cpus - 1);
@@ -1035,15 +1061,22 @@
     if (smp_call_function (ipi_handler, &data, 1, 0) != 0)
 	panic ("mtrr: timed out waiting for other CPUs\n");
     /* Flush and disable the local CPU's cache */
-    set_mtrr_prepare (&ctxt);
+    set_mtrr_prepare_save (&ctxt);
+    /*  Wait for all other CPUs to flush and disable their caches  */
+    while (atomic_read (&undone_count) > 0) { rep_nop(); barrier(); }
+    /* Set up for completion wait and then release other CPUs to change MTRRs*/
+    atomic_set (&undone_count, smp_num_cpus - 1);
+    wait_barrier_mtrr_disable = FALSE;
+    set_mtrr_disable (&ctxt);
+
     /*  Wait for all other CPUs to flush and disable their caches  */
-    while (atomic_read (&undone_count) > 0) barrier ();
+    while (atomic_read (&undone_count) > 0) { rep_nop(); barrier(); }
     /* Set up for completion wait and then release other CPUs to change MTRRs*/
     atomic_set (&undone_count, smp_num_cpus - 1);
     wait_barrier_execute = FALSE;
     (*set_mtrr_up) (reg, base, size, type, FALSE);
     /*  Now wait for other CPUs to complete the function  */
-    while (atomic_read (&undone_count) > 0) barrier ();
+    while (atomic_read (&undone_count) > 0) { rep_nop(); barrier(); }
     /*  Now all CPUs should have finished the function. Release the barrier to
 	allow them to re-enable their caches and return from their interrupt,
 	then enable the local cache and return  */
@@ -1889,7 +1922,9 @@
     struct set_mtrr_context ctxt;
     int i;
 
-    set_mtrr_prepare (&ctxt); /* flush cache and enable MAPEN */
+    /* flush cache and enable MAPEN */
+    set_mtrr_prepare_save (&ctxt);
+    set_mtrr_disable (&ctxt);
 
      /* the CCRs are not contiguous */
     for(i=0; i<4; i++) setCx86(CX86_CCR0 + i, ccr_state[i]);
@@ -1926,7 +1961,9 @@
     int i;
 #endif
 
-    set_mtrr_prepare (&ctxt); /* flush cache and enable MAPEN */
+    /* flush cache and enable MAPEN */
+    set_mtrr_prepare_save (&ctxt);
+    set_mtrr_disable (&ctxt);
 
     /* Save all CCRs locally */
     ccr[0] = getCx86 (CX86_CCR0);
@@ -2075,7 +2112,8 @@
 {
     struct set_mtrr_context ctxt;
 
-    set_mtrr_prepare (&ctxt);
+    set_mtrr_prepare_save (&ctxt);
+    set_mtrr_disable (&ctxt);
 
     if(boot_cpu_data.x86_model==4)
     	centaur_mcr0_init();
@@ -2192,7 +2230,8 @@
     /*  Note that this is not ideal, since the cache is only flushed/disabled
 	for this CPU while the MTRRs are changed, but changing this requires
 	more invasive changes to the way the kernel boots  */
-    set_mtrr_prepare (&ctxt);
+    set_mtrr_prepare_save (&ctxt);
+    set_mtrr_disable (&ctxt);
     mask = set_mtrr_state (&smp_mtrr_state, &ctxt);
     set_mtrr_done (&ctxt);
     /*  Use the atomic bitops to update the global mask  */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/i386/kernel/nmi.c linux/arch/i386/kernel/nmi.c
--- linux.orig/arch/i386/kernel/nmi.c	Fri Sep 21 03:55:24 2001
+++ linux/arch/i386/kernel/nmi.c	Tue May 28 22:39:29 2002
@@ -8,6 +8,7 @@
  *  Fixes:
  *  Mikael Pettersson	: AMD K7 support for local APIC NMI watchdog.
  *  Mikael Pettersson	: Power Management for local APIC NMI watchdog.
+ *  Mikael Pettersson	: Pentium 4 support for local APIC NMI watchdog.
  */
 
 #include <linux/config.h>
@@ -43,6 +44,32 @@
 #define P6_EVENT_CPU_CLOCKS_NOT_HALTED	0x79
 #define P6_NMI_EVENT		P6_EVENT_CPU_CLOCKS_NOT_HALTED
 
+#define MSR_P4_MISC_ENABLE	0x1A0
+#define MSR_P4_MISC_ENABLE_PERF_AVAIL	(1<<7)
+#define MSR_P4_MISC_ENABLE_PEBS_UNAVAIL	(1<<12)
+#define MSR_P4_PERFCTR0		0x300
+#define MSR_P4_CCCR0		0x360
+#define P4_ESCR_EVENT_SELECT(N)	((N)<<25)
+#define P4_ESCR_OS		(1<<3)
+#define P4_ESCR_USR		(1<<2)
+#define P4_CCCR_OVF_PMI		(1<<26)
+#define P4_CCCR_THRESHOLD(N)	((N)<<20)
+#define P4_CCCR_COMPLEMENT	(1<<19)
+#define P4_CCCR_COMPARE		(1<<18)
+#define P4_CCCR_REQUIRED	(3<<16)
+#define P4_CCCR_ESCR_SELECT(N)	((N)<<13)
+#define P4_CCCR_ENABLE		(1<<12)
+/* Set up IQ_COUNTER0 to behave like a clock, by having IQ_CCCR0 filter
+   CRU_ESCR0 (with any non-null event selector) through a complemented
+   max threshold. [IA32-Vol3, Section 14.9.9] */
+#define MSR_P4_IQ_COUNTER0	0x30C
+#define MSR_P4_IQ_CCCR0		0x36C
+#define MSR_P4_CRU_ESCR0	0x3B8
+#define P4_NMI_CRU_ESCR0	(P4_ESCR_EVENT_SELECT(0x3F)|P4_ESCR_OS|P4_ESCR_USR)
+#define P4_NMI_IQ_CCCR0	\
+	(P4_CCCR_OVF_PMI|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT|	\
+	 P4_CCCR_COMPARE|P4_CCCR_REQUIRED|P4_CCCR_ESCR_SELECT(4)|P4_CCCR_ENABLE)
+
 int __init check_nmi_watchdog (void)
 {
 	irq_cpustat_t tmp[NR_CPUS];
@@ -84,11 +111,11 @@
 	/*
 	 * If any other x86 CPU has a local APIC, then
 	 * please test the NMI stuff there and send me the
-	 * missing bits. Right now Intel P6 and AMD K7 only.
+	 * missing bits. Right now Intel P6/P4 and AMD K7 only.
 	 */
 	if ((nmi == NMI_LOCAL_APIC) &&
 			(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) &&
-			(boot_cpu_data.x86 == 6))
+			(boot_cpu_data.x86 == 6 || boot_cpu_data.x86 == 15))
 		nmi_watchdog = nmi;
 	if ((nmi == NMI_LOCAL_APIC) &&
 			(boot_cpu_data.x86_vendor == X86_VENDOR_AMD) &&
@@ -118,7 +145,15 @@
 		wrmsr(MSR_K7_EVNTSEL0, 0, 0);
 		break;
 	case X86_VENDOR_INTEL:
-		wrmsr(MSR_IA32_EVNTSEL0, 0, 0);
+		switch (boot_cpu_data.x86) {
+		case 6:
+			wrmsr(MSR_P6_EVNTSEL0, 0, 0);
+			break;
+		case 15:
+			wrmsr(MSR_P4_IQ_CCCR0, 0, 0);
+			wrmsr(MSR_P4_CRU_ESCR0, 0, 0);
+			break;
+		}
 		break;
 	}
 }
@@ -157,17 +192,22 @@
  * Original code written by Keith Owens.
  */
 
+static void __pminit clear_msr_range(unsigned int base, unsigned int n)
+{
+	unsigned int i;
+
+	for(i = 0; i < n; ++i)
+		wrmsr(base+i, 0, 0);
+}
+
 static void __pminit setup_k7_watchdog(void)
 {
-	int i;
 	unsigned int evntsel;
 
 	nmi_perfctr_msr = MSR_K7_PERFCTR0;
 
-	for(i = 0; i < 4; ++i) {
-		wrmsr(MSR_K7_EVNTSEL0+i, 0, 0);
-		wrmsr(MSR_K7_PERFCTR0+i, 0, 0);
-	}
+	clear_msr_range(MSR_K7_EVNTSEL0, 4);
+	clear_msr_range(MSR_K7_PERFCTR0, 4);
 
 	evntsel = K7_EVNTSEL_INT
 		| K7_EVNTSEL_OS
@@ -184,27 +224,54 @@
 
 static void __pminit setup_p6_watchdog(void)
 {
-	int i;
 	unsigned int evntsel;
 
-	nmi_perfctr_msr = MSR_IA32_PERFCTR0;
+	nmi_perfctr_msr = MSR_P6_PERFCTR0;
 
-	for(i = 0; i < 2; ++i) {
-		wrmsr(MSR_IA32_EVNTSEL0+i, 0, 0);
-		wrmsr(MSR_IA32_PERFCTR0+i, 0, 0);
-	}
+	clear_msr_range(MSR_P6_EVNTSEL0, 2);
+	clear_msr_range(MSR_P6_PERFCTR0, 2);
 
 	evntsel = P6_EVNTSEL_INT
 		| P6_EVNTSEL_OS
 		| P6_EVNTSEL_USR
 		| P6_NMI_EVENT;
 
-	wrmsr(MSR_IA32_EVNTSEL0, evntsel, 0);
-	Dprintk("setting IA32_PERFCTR0 to %08lx\n", -(cpu_khz/nmi_hz*1000));
-	wrmsr(MSR_IA32_PERFCTR0, -(cpu_khz/nmi_hz*1000), 0);
+	wrmsr(MSR_P6_EVNTSEL0, evntsel, 0);
+	Dprintk("setting P6_PERFCTR0 to %08lx\n", -(cpu_khz/nmi_hz*1000));
+	wrmsr(MSR_P6_PERFCTR0, -(cpu_khz/nmi_hz*1000), 0);
 	apic_write(APIC_LVTPC, APIC_DM_NMI);
 	evntsel |= P6_EVNTSEL0_ENABLE;
-	wrmsr(MSR_IA32_EVNTSEL0, evntsel, 0);
+	wrmsr(MSR_P6_EVNTSEL0, evntsel, 0);
+}
+
+static int __pminit setup_p4_watchdog(void)
+{
+	unsigned int misc_enable, dummy;
+
+	rdmsr(MSR_P4_MISC_ENABLE, misc_enable, dummy);
+	if (!(misc_enable & MSR_P4_MISC_ENABLE_PERF_AVAIL))
+		return 0;
+
+	nmi_perfctr_msr = MSR_P4_IQ_COUNTER0;
+
+	if (!(misc_enable & MSR_P4_MISC_ENABLE_PEBS_UNAVAIL))
+		clear_msr_range(0x3F1, 2);
+	/* MSR 0x3F0 seems to have a default value of 0xFC00, but current
+	   docs doesn't fully define it, so leave it alone for now. */
+	clear_msr_range(0x3A0, 31);
+	clear_msr_range(0x3C0, 6);
+	clear_msr_range(0x3C8, 6);
+	clear_msr_range(0x3E0, 2);
+	clear_msr_range(MSR_P4_CCCR0, 18);
+	clear_msr_range(MSR_P4_PERFCTR0, 18);
+
+	wrmsr(MSR_P4_CRU_ESCR0, P4_NMI_CRU_ESCR0, 0);
+	wrmsr(MSR_P4_IQ_CCCR0, P4_NMI_IQ_CCCR0 & ~P4_CCCR_ENABLE, 0);
+	Dprintk("setting P4_IQ_COUNTER0 to 0x%08lx\n", -(cpu_khz/nmi_hz*1000));
+	wrmsr(MSR_P4_IQ_COUNTER0, -(cpu_khz/nmi_hz*1000), -1);
+	apic_write(APIC_LVTPC, APIC_DM_NMI);
+	wrmsr(MSR_P4_IQ_CCCR0, P4_NMI_IQ_CCCR0, 0);
+	return 1;
 }
 
 void __pminit setup_apic_nmi_watchdog (void)
@@ -216,9 +283,17 @@
 		setup_k7_watchdog();
 		break;
 	case X86_VENDOR_INTEL:
-		if (boot_cpu_data.x86 != 6)
+		switch (boot_cpu_data.x86) {
+		case 6:
+			setup_p6_watchdog();
+			break;
+		case 15:
+			if (!setup_p4_watchdog())
+				return;
+			break;
+		default:
 			return;
-		setup_p6_watchdog();
+		}
 		break;
 	default:
 		return;
@@ -283,7 +358,7 @@
 			 * to get a message out.
 			 */
 			bust_spinlocks(1);
-			printk("NMI Watchdog detected LOCKUP on CPU%d, registers:\n", cpu);
+			printk("NMI Watchdog detected LOCKUP on CPU%d, eip %08lx, registers:\n", cpu, regs->eip);
 			show_registers(regs);
 			printk("console shuts up ...\n");
 			console_silent();
@@ -295,6 +370,18 @@
 		last_irq_sums[cpu] = sum;
 		alert_counter[cpu] = 0;
 	}
-	if (nmi_perfctr_msr)
+	if (nmi_perfctr_msr) {
+		if (nmi_perfctr_msr == MSR_P4_IQ_COUNTER0) {
+			/*
+			 * P4 quirks:
+			 * - An overflown perfctr will assert its interrupt
+			 *   until the OVF flag in its CCCR is cleared.
+			 * - LVTPC is masked on interrupt and must be
+			 *   unmasked by the LVTPC handler.
+			 */
+			wrmsr(MSR_P4_IQ_CCCR0, P4_NMI_IQ_CCCR0, 0);
+			apic_write(APIC_LVTPC, APIC_DM_NMI);
+		}
 		wrmsr(nmi_perfctr_msr, -(cpu_khz/nmi_hz*1000), -1);
+	}
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/i386/kernel/pci-irq.c linux/arch/i386/kernel/pci-irq.c
--- linux.orig/arch/i386/kernel/pci-irq.c	Mon Feb 25 19:37:53 2002
+++ linux/arch/i386/kernel/pci-irq.c	Tue May 28 22:39:31 2002
@@ -206,6 +206,24 @@
 }
 
 /*
+ * ITE 8330G pirq rules are nibble-based
+ * FIXME: pirqmap may be { 1, 0, 3, 2 },
+ * 	  2+3 are both mapped to irq 9 on my system
+ */
+static int pirq_ite_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
+{
+	static unsigned char pirqmap[4] = { 1, 0, 2, 3 };
+	return read_config_nybble(router,0x43, pirqmap[pirq-1]);
+}
+
+static int pirq_ite_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
+{
+	static unsigned char pirqmap[4] = { 1, 0, 2, 3 };
+	write_config_nybble(router, 0x43, pirqmap[pirq-1], irq);
+	return 1;
+}
+
+/*
  * OPTI: high four bits are nibble pointer..
  * I wonder what the low bits do?
  */
@@ -443,9 +461,16 @@
 	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0, pirq_piix_get, pirq_piix_set },
 	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371MX,   pirq_piix_get, pirq_piix_set },
 	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_0, pirq_piix_get, pirq_piix_set },
+	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, pirq_piix_get, pirq_piix_set },
+	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0, pirq_piix_get, pirq_piix_set },
 	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, pirq_piix_get, pirq_piix_set },
+	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_10, pirq_piix_get, pirq_piix_set },
+	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, pirq_piix_get, pirq_piix_set },
+	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, pirq_piix_get, pirq_piix_set },
 
 	{ "ALI", PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, pirq_ali_get, pirq_ali_set },
+
+	{ "ITE", PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_IT8330G_0, pirq_ite_get, pirq_ite_set },
 
 	{ "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, pirq_via_get, pirq_via_set },
 	{ "VIA", PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596, pirq_via_get, pirq_via_set },
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/i386/kernel/pci-pc.c linux/arch/i386/kernel/pci-pc.c
--- linux.orig/arch/i386/kernel/pci-pc.c	Mon Feb 25 19:37:53 2002
+++ linux/arch/i386/kernel/pci-pc.c	Tue May 28 22:39:25 2002
@@ -14,6 +14,7 @@
 
 #include <asm/segment.h>
 #include <asm/io.h>
+#include <asm/smp.h>
 
 #include "pci-i386.h"
 
@@ -26,6 +27,16 @@
 int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value) = NULL;
 int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 value) = NULL;
 
+#ifdef CONFIG_MULTIQUAD
+#define BUS2QUAD(global) (mp_bus_id_to_node[global])
+#define BUS2LOCAL(global) (mp_bus_id_to_local[global])
+#define QUADLOCAL2BUS(quad,local) (quad_local_to_mp_bus_id[quad][local])
+#else
+#define BUS2QUAD(global) (0)
+#define BUS2LOCAL(global) (global)
+#define QUADLOCAL2BUS(quad,local) (local)
+#endif
+
 /*
  * This interrupt-safe spinlock protects all accesses to PCI
  * configuration space.
@@ -39,10 +50,71 @@
 
 #ifdef CONFIG_PCI_DIRECT
 
+#ifdef CONFIG_MULTIQUAD
+#define PCI_CONF1_ADDRESS(bus, dev, fn, reg) \
+	(0x80000000 | (BUS2LOCAL(bus) << 16) | (dev << 11) | (fn << 8) | (reg & ~3))
+
+static int pci_conf1_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value) /* CONFIG_MULTIQUAD */
+{
+	unsigned long flags;
+
+	if (!value || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
+		return -EINVAL;
+
+	spin_lock_irqsave(&pci_config_lock, flags);
+
+	outl_quad(PCI_CONF1_ADDRESS(bus, dev, fn, reg), 0xCF8, BUS2QUAD(bus));
+
+	switch (len) {
+	case 1:
+		*value = inb_quad(0xCFC + (reg & 3), BUS2QUAD(bus));
+		break;
+	case 2:
+		*value = inw_quad(0xCFC + (reg & 2), BUS2QUAD(bus));
+		break;
+	case 4:
+		*value = inl_quad(0xCFC, BUS2QUAD(bus));
+		break;
+	}
+
+	spin_unlock_irqrestore(&pci_config_lock, flags);
+
+	return 0;
+}
+
+static int pci_conf1_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value) /* CONFIG_MULTIQUAD */
+{
+	unsigned long flags;
+
+	if ((bus > 255) || (dev > 31) || (fn > 7) || (reg > 255)) 
+		return -EINVAL;
+
+	spin_lock_irqsave(&pci_config_lock, flags);
+
+	outl_quad(PCI_CONF1_ADDRESS(bus, dev, fn, reg), 0xCF8, BUS2QUAD(bus));
+
+	switch (len) {
+	case 1:
+		outb_quad((u8)value, 0xCFC + (reg & 3), BUS2QUAD(bus));
+		break;
+	case 2:
+		outw_quad((u16)value, 0xCFC + (reg & 2), BUS2QUAD(bus));
+		break;
+	case 4:
+		outl_quad((u32)value, 0xCFC, BUS2QUAD(bus));
+		break;
+	}
+
+	spin_unlock_irqrestore(&pci_config_lock, flags);
+
+	return 0;
+}
+
+#else /* !CONFIG_MULTIQUAD */
 #define PCI_CONF1_ADDRESS(bus, dev, fn, reg) \
 	(0x80000000 | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3))
 
-static int pci_conf1_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
+static int pci_conf1_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value) /* !CONFIG_MULTIQUAD */
 {
 	unsigned long flags;
 
@@ -70,7 +142,7 @@
 	return 0;
 }
 
-static int pci_conf1_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
+static int pci_conf1_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value) /* !CONFIG_MULTIQUAD */
 {
 	unsigned long flags;
 
@@ -98,6 +170,8 @@
 	return 0;
 }
 
+#endif /* CONFIG_MULTIQUAD */
+
 #undef PCI_CONF1_ADDRESS
 
 static int pci_conf1_read_config_byte(struct pci_dev *dev, int where, u8 *value)
@@ -347,7 +421,7 @@
 		    pci_sanity_check(&pci_direct_conf1)) {
 			outl (tmp, 0xCF8);
 			__restore_flags(flags);
-			printk("PCI: Using configuration type 1\n");
+			printk(KERN_INFO "PCI: Using configuration type 1\n");
 			request_region(0xCF8, 8, "PCI conf1");
 			return &pci_direct_conf1;
 		}
@@ -364,7 +438,7 @@
 		if (inb (0xCF8) == 0x00 && inb (0xCFA) == 0x00 &&
 		    pci_sanity_check(&pci_direct_conf2)) {
 			__restore_flags(flags);
-			printk("PCI: Using configuration type 2\n");
+			printk(KERN_INFO "PCI: Using configuration type 2\n");
 			request_region(0xCF8, 4, "PCI conf2");
 			return &pci_direct_conf2;
 		}
@@ -472,10 +546,10 @@
 		case 0:
 			return address + entry;
 		case 0x80:	/* Not present */
-			printk("bios32_service(0x%lx): not present\n", service);
+			printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
 			return 0;
 		default: /* Shouldn't happen */
-			printk("bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
+			printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
 				service, return_code);
 			return 0;
 	}
@@ -525,7 +599,7 @@
 				status, signature);
 			return 0;
 		}
-		printk("PCI: PCI BIOS revision %x.%02x entry at 0x%lx, last bus=%d\n",
+		printk(KERN_INFO "PCI: PCI BIOS revision %x.%02x entry at 0x%lx, last bus=%d\n",
 			major_ver, minor_ver, pcibios_entry, pcibios_last_bus);
 #ifdef CONFIG_PCI_DIRECT
 		if (!(hw_mech & PCIBIOS_HW_TYPE1))
@@ -827,7 +901,7 @@
 				}
 			}
 			if (ln == &pci_devices) {
-				printk("PCI: BIOS reporting unknown device %02x:%02x\n", bus, devfn);
+				printk(KERN_WARNING "PCI: BIOS reporting unknown device %02x:%02x\n", bus, devfn);
 				/*
 				 * We must not continue scanning as several buggy BIOSes
 				 * return garbage after the last device. Grr.
@@ -836,7 +910,7 @@
 			}
 		}
 		if (!found) {
-			printk("PCI: Device %02x:%02x not found by BIOS\n",
+			printk(KERN_WARNING "PCI: Device %02x:%02x not found by BIOS\n",
 				dev->bus->number, dev->devfn);
 			list_del(&dev->global_list);
 			list_add_tail(&dev->global_list, &sorted_devices);
@@ -896,7 +970,7 @@
 			rt->size = opt.size + sizeof(struct irq_routing_table);
 			rt->exclusive_irqs = map;
 			memcpy(rt->slots, (void *) page, opt.size);
-			printk("PCI: Using BIOS Interrupt Routing Table\n");
+			printk(KERN_INFO "PCI: Using BIOS Interrupt Routing Table\n");
 		}
 	}
 	free_page(page);
@@ -961,7 +1035,7 @@
 	}
 	if (!seen_host_bridge)
 		return;
-	printk("PCI: Ignoring ghost devices on bus %02x\n", b->number);
+	printk(KERN_WARNING "PCI: Ignoring ghost devices on bus %02x\n", b->number);
 
 	ln = &b->devices;
 	while (ln->next != &b->devices) {
@@ -999,7 +1073,7 @@
 			if (!pci_read_config_word(&dev, PCI_VENDOR_ID, &l) &&
 			    l != 0x0000 && l != 0xffff) {
 				DBG("Found device at %02x:%02x [%04x]\n", n, dev.devfn, l);
-				printk("PCI: Discovered peer bus %02x\n", n);
+				printk(KERN_INFO "PCI: Discovered peer bus %02x\n", n);
 				pci_scan_bus(n, pci_root_ops, NULL);
 				break;
 			}
@@ -1017,6 +1091,9 @@
 	 */
 	int pxb, reg;
 	u8 busno, suba, subb;
+#ifdef CONFIG_MULTIQUAD
+	int quad = BUS2QUAD(d->bus->number);
+#endif
 	printk("PCI: Searching for i450NX host bridges on %s\n", d->slot_name);
 	reg = 0xd0;
 	for(pxb=0; pxb<2; pxb++) {
@@ -1025,9 +1102,9 @@
 		pci_read_config_byte(d, reg++, &subb);
 		DBG("i450NX PXB %d: %02x/%02x/%02x\n", pxb, busno, suba, subb);
 		if (busno)
-			pci_scan_bus(busno, pci_root_ops, NULL);	/* Bus A */
+			pci_scan_bus(QUADLOCAL2BUS(quad,busno), pci_root_ops, NULL);	/* Bus A */
 		if (suba < subb)
-			pci_scan_bus(suba+1, pci_root_ops, NULL);	/* Bus B */
+			pci_scan_bus(QUADLOCAL2BUS(quad,suba+1), pci_root_ops, NULL);	/* Bus B */
 	}
 	pcibios_last_bus = -1;
 }
@@ -1040,7 +1117,7 @@
 	 */
 	u8 busno;
 	pci_read_config_byte(d, 0x4a, &busno);
-	printk("PCI: i440KX/GX host bridge %s: secondary bus %02x\n", d->slot_name, busno);
+	printk(KERN_INFO "PCI: i440KX/GX host bridge %s: secondary bus %02x\n", d->slot_name, busno);
 	pci_scan_bus(busno, pci_root_ops, NULL);
 	pcibios_last_bus = -1;
 }
@@ -1053,7 +1130,7 @@
 	 */
 	int i;
 
-	printk("PCI: Fixing base address flags for device %s\n", d->slot_name);
+	printk(KERN_WARNING "PCI: Fixing base address flags for device %s\n", d->slot_name);
 	for(i=0; i<4; i++)
 		d->resource[i].flags |= PCI_BASE_ADDRESS_SPACE_IO;
 }
@@ -1110,27 +1187,48 @@
 
 /*
  * Addresses issues with problems in the memory write queue timer in
- * certain VIA Northbridges.  This bugfix is per VIA's specifications.
- *
+ * certain VIA Northbridges.  This bugfix is per VIA's specifications,
+ * except for the KL133/KM133: clearing bit 5 on those Northbridges seems
+ * to trigger a bug in its integrated ProSavage video card, which
+ * causes screen corruption.  We only clear bits 6 and 7 for that chipset,
+ * until VIA can provide us with definitive information on why screen
+ * corruption occurs, and what exactly those bits do.
+ * 
  * VIA 8363,8622,8361 Northbridges:
  *  - bits  5, 6, 7 at offset 0x55 need to be turned off
  * VIA 8367 (KT266x) Northbridges:
  *  - bits  5, 6, 7 at offset 0x95 need to be turned off
+ * VIA 8363 rev 0x81/0x84 (KL133/KM133) Northbridges:
+ *  - bits     6, 7 at offset 0x55 need to be turned off
  */
+
+#define VIA_8363_KL133_REVISION_ID 0x81
+#define VIA_8363_KM133_REVISION_ID 0x84
+
 static void __init pci_fixup_via_northbridge_bug(struct pci_dev *d)
 {
 	u8 v;
+	u8 revision;
 	int where = 0x55;
+	int mask = 0x1f; /* clear bits 5, 6, 7 by default */
 
+	pci_read_config_byte(d, PCI_REVISION_ID, &revision);
+	
 	if (d->device == PCI_DEVICE_ID_VIA_8367_0) {
 		where = 0x95; /* the memory write queue timer register is 
-				 different for the kt266x's: 0x95 not 0x55 */
+				 different for the KT266x's: 0x95 not 0x55 */
+	} else if (d->device == PCI_DEVICE_ID_VIA_8363_0 &&
+	           (revision == VIA_8363_KL133_REVISION_ID || 
+		    revision == VIA_8363_KM133_REVISION_ID)) {
+		mask = 0x3f; /* clear only bits 6 and 7; clearing bit 5
+				causes screen corruption on the KL133/KM133 */
 	}
 
 	pci_read_config_byte(d, where, &v);
-	if (v & 0xe0) {
-		printk("Disabling VIA memory write queue: [%02x] %02x->%02x\n", where, v, v & 0x1f);
-		v &= 0x1f; /* clear bits 5, 6, 7 */
+	if (v & ~mask) {
+		printk("Disabling VIA memory write queue (PCI ID %04x, rev %02x): [%02x] %02x & %02x -> %02x\n", \
+			d->device, revision, where, v, mask, v & mask);
+		v &= mask;
 		pci_write_config_byte(d, where, v);
 	}
 }
@@ -1199,15 +1297,25 @@
 
 void __init pcibios_init(void)
 {
+	int quad;
+
 	if (!pci_root_ops)
 		pcibios_config_init();
 	if (!pci_root_ops) {
-		printk("PCI: System does not support PCI\n");
+		printk(KERN_WARNING "PCI: System does not support PCI\n");
 		return;
 	}
 
-	printk("PCI: Probing PCI hardware\n");
+	printk(KERN_INFO "PCI: Probing PCI hardware\n");
 	pci_root_bus = pci_scan_bus(0, pci_root_ops, NULL);
+	if (clustered_apic_mode && (numnodes > 1)) {
+		for (quad = 1; quad < numnodes; ++quad) {
+			printk("Scanning PCI bus %d for quad %d\n", 
+				QUADLOCAL2BUS(quad,0), quad);
+			pci_scan_bus(QUADLOCAL2BUS(quad,0), 
+				pci_root_ops, NULL);
+		}
+	}
 
 	pcibios_irq_init();
 	pcibios_fixup_peer_bridges();
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/i386/kernel/semaphore.c linux/arch/i386/kernel/semaphore.c
--- linux.orig/arch/i386/kernel/semaphore.c	Fri Nov  9 21:58:02 2001
+++ linux/arch/i386/kernel/semaphore.c	Tue May 28 22:39:25 2002
@@ -182,6 +182,10 @@
 ".align 4\n"
 ".globl __down_failed\n"
 "__down_failed:\n\t"
+#if defined(CONFIG_FRAME_POINTER)
+	"pushl %ebp\n\t"
+	"movl  %esp,%ebp\n\t"
+#endif
 	"pushl %eax\n\t"
 	"pushl %edx\n\t"
 	"pushl %ecx\n\t"
@@ -189,6 +193,10 @@
 	"popl %ecx\n\t"
 	"popl %edx\n\t"
 	"popl %eax\n\t"
+#if defined(CONFIG_FRAME_POINTER)
+	"movl %ebp,%esp\n\t"
+	"popl %ebp\n\t"
+#endif
 	"ret"
 );
 
@@ -197,11 +205,19 @@
 ".align 4\n"
 ".globl __down_failed_interruptible\n"
 "__down_failed_interruptible:\n\t"
+#if defined(CONFIG_FRAME_POINTER)
+	"pushl %ebp\n\t"
+	"movl  %esp,%ebp\n\t"
+#endif
 	"pushl %edx\n\t"
 	"pushl %ecx\n\t"
 	"call __down_interruptible\n\t"
 	"popl %ecx\n\t"
 	"popl %edx\n\t"
+#if defined(CONFIG_FRAME_POINTER)
+	"movl %ebp,%esp\n\t"
+	"popl %ebp\n\t"
+#endif
 	"ret"
 );
 
@@ -210,11 +226,19 @@
 ".align 4\n"
 ".globl __down_failed_trylock\n"
 "__down_failed_trylock:\n\t"
+#if defined(CONFIG_FRAME_POINTER)
+	"pushl %ebp\n\t"
+	"movl  %esp,%ebp\n\t"
+#endif
 	"pushl %edx\n\t"
 	"pushl %ecx\n\t"
 	"call __down_trylock\n\t"
 	"popl %ecx\n\t"
 	"popl %edx\n\t"
+#if defined(CONFIG_FRAME_POINTER)
+	"movl %ebp,%esp\n\t"
+	"popl %ebp\n\t"
+#endif
 	"ret"
 );
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c
--- linux.orig/arch/i386/kernel/setup.c	Mon Feb 25 19:37:53 2002
+++ linux/arch/i386/kernel/setup.c	Tue May 28 22:39:27 2002
@@ -98,6 +98,8 @@
 #endif
 #include <linux/highmem.h>
 #include <linux/bootmem.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
 #include <linux/seq_file.h>
 #include <asm/processor.h>
 #include <linux/console.h>
@@ -139,6 +141,9 @@
 /* For PCI or other memory-mapped resources */
 unsigned long pci_mem_start = 0x10000000;
 
+/* user-defined highmem size */
+static unsigned int highmem_pages __initdata = -1;
+
 /*
  * Setup options
  */
@@ -155,11 +160,13 @@
 unsigned char aux_device_present;
 
 extern void mcheck_init(struct cpuinfo_x86 *c);
+extern void dmi_scan_machine(void);
 extern int root_mountflags;
 extern char _text, _etext, _edata, _end;
 
 static int disable_x86_serial_nr __initdata = 1;
 static int disable_x86_fxsr __initdata = 0;
+static int disable_x86_ht __initdata = 0;
 
 int enable_acpi_smp_table;
 
@@ -408,6 +415,22 @@
 	}
 }
 
+static void __init limit_regions (unsigned long long size)
+{
+	unsigned long long current_addr = 0;
+	int i;
+
+	for (i = 0; i < e820.nr_map; i++) {
+		if (e820.map[i].type == E820_RAM) {
+			current_addr = e820.map[i].addr + e820.map[i].size;
+			if (current_addr >= size) {
+				e820.map[i].size -= current_addr-size;
+				e820.nr_map = i + 1;
+				return;
+			}
+		}
+	}
+}
 static void __init add_memory_region(unsigned long long start,
                                   unsigned long long size, int type)
 {
@@ -705,17 +728,19 @@
 } /* setup_memory_region */
 
 
-static void __init parse_mem_cmdline (char ** cmdline_p)
+static void __init parse_cmdline_early (char ** cmdline_p)
 {
 	char c = ' ', *to = command_line, *from = COMMAND_LINE;
 	int len = 0;
-	int usermem = 0;
+	int userdef = 0;
 
 	/* Save unparsed command line copy for /proc/cmdline */
 	memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
 	saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
 
 	for (;;) {
+		if (c != ' ')
+			goto nextchar;
 		/*
 		 * "mem=nopentium" disables the 4MB page tables.
 		 * "mem=XXX[kKmM]" defines a memory region from HIGH_MEM
@@ -723,7 +748,7 @@
 		 * "mem=XXX[KkmM]@XXX[KkmM]" defines a memory region from
 		 * <start> to <start>+<mem>, overriding the bios size.
 		 */
-		if (c == ' ' && !memcmp(from, "mem=", 4)) {
+		if (!memcmp(from, "mem=", 4)) {
 			if (to != command_line)
 				to--;
 			if (!memcmp(from+4, "nopentium", 9)) {
@@ -732,38 +757,43 @@
 			} else if (!memcmp(from+4, "exactmap", 8)) {
 				from += 8+4;
 				e820.nr_map = 0;
-				usermem = 1;
+				userdef = 1;
 			} else {
 				/* If the user specifies memory size, we
-				 * blow away any automatically generated
-				 * size
+				 * limit the BIOS-provided memory map to
+				 * that size. exactmap can be used to specify
+				 * the exact map. mem=number can be used to
+				 * trim the existing memory map.
 				 */
 				unsigned long long start_at, mem_size;
  
-				if (usermem == 0) {
-					/* first time in: zap the whitelist
-					 * and reinitialize it with the
-					 * standard low-memory region.
-					 */
-					e820.nr_map = 0;
-					usermem = 1;
-					add_memory_region(0, LOWMEMSIZE(), E820_RAM);
-				}
 				mem_size = memparse(from+4, &from);
-				if (*from == '@')
+				if (*from == '@') {
 					start_at = memparse(from+1, &from);
-				else {
-					start_at = HIGH_MEMORY;
-					mem_size -= HIGH_MEMORY;
-					usermem=0;
+					add_memory_region(start_at, mem_size, E820_RAM);
+				} else {
+					limit_regions(mem_size);
+					userdef=1;
 				}
-				add_memory_region(start_at, mem_size, E820_RAM);
 			}
 		}
-		/* acpismp=force forces parsing and use of the ACPI SMP table */
-		if (c == ' ' && !memcmp(from, "acpismp=force", 13)) 	
-			 enable_acpi_smp_table = 1;
-	
+
+		/* "noht" disables HyperThreading (2 logical cpus per Xeon) */
+		else if (!memcmp(from, "noht", 4))
+			disable_x86_ht = 1;
+
+		/* "acpismp=force" forces parsing and use of the ACPI SMP table */
+		else if (!memcmp(from, "acpismp=force", 13))
+			enable_acpi_smp_table = 1;
+
+		/*
+		 * highmem=size forces highmem to be exactly 'size' bytes.
+		 * This works even on boxes that have no highmem otherwise.
+		 * This also works to reduce highmem size on bigger boxes.
+		 */
+		else if (!memcmp(from, "highmem=", 8))
+			highmem_pages = memparse(from+8, &from) >> PAGE_SHIFT;
+nextchar:
 		c = *(from++);
 		if (!c)
 			break;
@@ -773,7 +803,7 @@
 	}
 	*to = '\0';
 	*cmdline_p = command_line;
-	if (usermem) {
+	if (userdef) {
 		printk(KERN_INFO "user-defined physical RAM map:\n");
 		print_memory_map("user");
 	}
@@ -820,7 +850,7 @@
 	data_resource.start = virt_to_bus(&_etext);
 	data_resource.end = virt_to_bus(&_edata)-1;
 
-	parse_mem_cmdline(cmdline_p);
+	parse_cmdline_early(cmdline_p);
 
 #define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
 #define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
@@ -860,6 +890,14 @@
 	 */
 	max_low_pfn = max_pfn;
 	if (max_low_pfn > MAXMEM_PFN) {
+		if (highmem_pages == -1)
+			highmem_pages = max_pfn - MAXMEM_PFN;
+		if (highmem_pages + MAXMEM_PFN < max_pfn)
+			max_pfn = MAXMEM_PFN + highmem_pages;
+		if (highmem_pages + MAXMEM_PFN > max_pfn) {
+			printk("only %luMB highmem pages available, ignoring highmem size of %uMB.\n", pages_to_mb(max_pfn - MAXMEM_PFN), pages_to_mb(highmem_pages));
+			highmem_pages = 0;
+		}
 		max_low_pfn = MAXMEM_PFN;
 #ifndef CONFIG_HIGHMEM
 		/* Maximum memory usable is what is directly addressable */
@@ -878,16 +916,37 @@
 		}
 #endif /* !CONFIG_X86_PAE */
 #endif /* !CONFIG_HIGHMEM */
+	} else {
+		if (highmem_pages == -1)
+			highmem_pages = 0;
+#if CONFIG_HIGHMEM
+		if (highmem_pages >= max_pfn) {
+			printk(KERN_ERR "highmem size specified (%uMB) is bigger than pages available (%luMB)!.\n", pages_to_mb(highmem_pages), pages_to_mb(max_pfn));
+			highmem_pages = 0;
+		}
+		if (highmem_pages) {
+			if (max_low_pfn-highmem_pages < 64*1024*1024/PAGE_SIZE){
+				printk(KERN_ERR "highmem size %uMB results in smaller than 64MB lowmem, ignoring it.\n", pages_to_mb(highmem_pages));
+				highmem_pages = 0;
+			}
+			max_low_pfn -= highmem_pages;
+		}
+#else
+		if (highmem_pages)
+			printk(KERN_ERR "ignoring highmem size on non-highmem kernel!\n");
+#endif
 	}
 
 #ifdef CONFIG_HIGHMEM
 	highstart_pfn = highend_pfn = max_pfn;
-	if (max_pfn > MAXMEM_PFN) {
-		highstart_pfn = MAXMEM_PFN;
-		printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
-			pages_to_mb(highend_pfn - highstart_pfn));
+	if (max_pfn > max_low_pfn) {
+		highstart_pfn = max_low_pfn;
 	}
+	printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
+		pages_to_mb(highend_pfn - highstart_pfn));
 #endif
+	printk(KERN_NOTICE "%ldMB LOWMEM available.\n",
+			pages_to_mb(max_low_pfn));
 	/*
 	 * Initialize the boot-time allocator (with low memory only):
 	 */
@@ -976,6 +1035,21 @@
 #endif
 
 	/*
+	 * If enable_acpi_smp_table and HT feature present, acpitable.c
+	 * will find all logical cpus despite disable_x86_ht: so if both
+	 * "noht" and "acpismp=force" are specified, let "noht" override
+	 * "acpismp=force" cleanly.  Why retain "acpismp=force"? because
+	 * parsing ACPI SMP table might prove useful on some non-HT cpu.
+	 */
+	if (disable_x86_ht) {
+		clear_bit(X86_FEATURE_HT, &boot_cpu_data.x86_capability[0]);
+		enable_acpi_smp_table = 0;
+	}
+	if (test_bit(X86_FEATURE_HT, &boot_cpu_data.x86_capability[0]))
+		enable_acpi_smp_table = 1;
+	
+
+	/*
 	 * NOTE: before this point _nobody_ is allowed to allocate
 	 * any memory using the bootmem allocator.
 	 */
@@ -990,7 +1064,6 @@
 	 */
 	if (smp_found_config)
 		get_smp_config();
-	init_apic_mappings();
 #endif
 
 
@@ -1042,6 +1115,7 @@
 	conswitchp = &dummy_con;
 #endif
 #endif
+	dmi_scan_machine();
 }
 
 static int cachesize_override __initdata = -1;
@@ -1306,7 +1380,7 @@
 }
 
 /*
- * Read Cyrix DEVID registers (DIR) to get more detailed info. about the CPU
+ * Read NSC/Cyrix DEVID registers (DIR) to get more detailed info. about the CPU
  */
 static void __init do_cyrix_devid(unsigned char *dir0, unsigned char *dir1)
 {
@@ -1468,11 +1542,6 @@
 		break;
 
 	case 4: /* MediaGX/GXm */
-		/*
-		 *	Life sometimes gets weiiiiiiiird if we use this
-		 *	on the MediaGX. So we turn it off for now. 
-		 */
-		
 #ifdef CONFIG_PCI
 		/* It isnt really a PCI quirk directly, but the cure is the
 		   same. The MediaGX has deep magic SMM stuff that handles the
@@ -1494,14 +1563,22 @@
 		/* GXm supports extended cpuid levels 'ala' AMD */
 		if (c->cpuid_level == 2) {
 			get_model_name(c);  /* get CPU marketing name */
-			clear_bit(X86_FEATURE_TSC, c->x86_capability);
+			/*
+	 		 *	The 5510/5520 companion chips have a funky PIT
+			 *	that breaks the TSC synchronizing, so turn it off
+			 */
+			if(pci_find_device(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510, NULL) ||
+			   pci_find_device(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520, NULL))
+				clear_bit(X86_FEATURE_TSC, c->x86_capability);
 			return;
 		}
 		else {  /* MediaGX */
 			Cx86_cb[2] = (dir0_lsn & 1) ? '3' : '4';
 			p = Cx86_cb+2;
 			c->x86_model = (dir1 & 0x20) ? 1 : 2;
-			clear_bit(X86_FEATURE_TSC, &c->x86_capability);
+			if(pci_find_device(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510, NULL) ||
+			   pci_find_device(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520, NULL))
+				clear_bit(X86_FEATURE_TSC, &c->x86_capability);
 		}
 		break;
 
@@ -2210,7 +2287,7 @@
 		strcpy(c->x86_model_id, p);
 	
 #ifdef CONFIG_SMP
-	if (test_bit(X86_FEATURE_HT, &c->x86_capability)) {
+	if (test_bit(X86_FEATURE_HT, &c->x86_capability) && !disable_x86_ht) {
 		extern	int phys_proc_id[NR_CPUS];
 		
 		u32 	eax, ebx, ecx, edx;
@@ -2270,6 +2347,8 @@
 		c->x86_vendor = X86_VENDOR_AMD;
 	else if (!strcmp(v, "CyrixInstead"))
 		c->x86_vendor = X86_VENDOR_CYRIX;
+	else if (!strcmp(v, "Geode by NSC"))
+		c->x86_vendor = X86_VENDOR_NSC;
 	else if (!strcmp(v, "UMC UMC UMC "))
 		c->x86_vendor = X86_VENDOR_UMC;
 	else if (!strcmp(v, "CentaurHauls"))
@@ -2613,6 +2692,10 @@
 		init_cyrix(c);
 		break;
 
+	case X86_VENDOR_NSC:
+	        init_cyrix(c);
+		break;
+
 	case X86_VENDOR_AMD:
 		init_amd(c);
 		break;
@@ -2655,6 +2738,10 @@
 		clear_bit(X86_FEATURE_TSC, &c->x86_capability);
 #endif
 
+	/* HT disabled? */
+	if (disable_x86_ht)
+		clear_bit(X86_FEATURE_HT, &c->x86_capability);
+
 	/* FXSR disabled? */
 	if (disable_x86_fxsr) {
 		clear_bit(X86_FEATURE_FXSR, &c->x86_capability);
@@ -2713,14 +2800,17 @@
 {
 	get_cpu_vendor(&boot_cpu_data);
 
-	if ( boot_cpu_data.x86_vendor == X86_VENDOR_CYRIX )
+	if ( boot_cpu_data.x86_vendor == X86_VENDOR_CYRIX ||
+	     boot_cpu_data.x86_vendor == X86_VENDOR_NSC )
 		init_cyrix(&boot_cpu_data);
 }
 
 
 /* These need to match <asm/processor.h> */
 static char *cpu_vendor_names[] __initdata = {
-	"Intel", "Cyrix", "AMD", "UMC", "NexGen", "Centaur", "Rise", "Transmeta" };
+	"Intel", "Cyrix", "AMD", "UMC", "NexGen", 
+	"Centaur", "Rise", "Transmeta", "NSC"
+};
 
 
 void __init print_cpu_info(struct cpuinfo_x86 *c)
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/i386/kernel/signal.c linux/arch/i386/kernel/signal.c
--- linux.orig/arch/i386/kernel/signal.c	Mon Feb 25 19:37:53 2002
+++ linux/arch/i386/kernel/signal.c	Tue May 28 22:39:26 2002
@@ -685,10 +685,7 @@
 				/* FALLTHRU */
 
 			default:
-				sigaddset(&current->pending.signal, signr);
-				recalc_sigpending(current);
-				current->flags |= PF_SIGNALED;
-				do_exit(exit_code);
+				sig_exit(signr, exit_code, &info);
 				/* NOTREACHED */
 			}
 		}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/i386/kernel/smp.c linux/arch/i386/kernel/smp.c
--- linux.orig/arch/i386/kernel/smp.c	Fri Dec 21 17:41:53 2001
+++ linux/arch/i386/kernel/smp.c	Tue May 28 22:39:16 2002
@@ -103,9 +103,9 @@
  */
 
 /* The 'big kernel lock' */
-spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
+spinlock_cacheline_t kernel_flag_cacheline = {SPIN_LOCK_UNLOCKED};
 
-struct tlb_state cpu_tlbstate[NR_CPUS] = {[0 ... NR_CPUS-1] = { &init_mm, 0 }};
+struct tlb_state cpu_tlbstate[NR_CPUS] __cacheline_aligned = {[0 ... NR_CPUS-1] = { &init_mm, 0, }};
 
 /*
  * the following functions deal with sending IPIs between CPUs.
@@ -301,8 +301,7 @@
  */
 static void inline leave_mm (unsigned long cpu)
 {
-	if (cpu_tlbstate[cpu].state == TLBSTATE_OK)
-		BUG();
+	BUG_ON(cpu_tlbstate[cpu].state == TLBSTATE_OK);
 	clear_bit(cpu, &cpu_tlbstate[cpu].active_mm->cpu_vm_mask);
 }
 
@@ -529,7 +528,7 @@
  * remote CPUs are nearly ready to execute <<func>> or are or have executed.
  *
  * You must not call this function with disabled interrupts or from a
- * hardware interrupt handler, you may call it from a bottom half handler.
+ * hardware interrupt handler or from a bottom half handler.
  */
 {
 	struct call_data_struct data;
@@ -545,7 +544,7 @@
 	if (wait)
 		atomic_set(&data.finished, 0);
 
-	spin_lock_bh(&call_lock);
+	spin_lock(&call_lock);
 	call_data = &data;
 	wmb();
 	/* Send a message to all other CPUs and wait for them to respond */
@@ -558,7 +557,7 @@
 	if (wait)
 		while (atomic_read(&data.finished) != cpus)
 			barrier();
-	spin_unlock_bh(&call_lock);
+	spin_unlock(&call_lock);
 
 	return 0;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/i386/kernel/smpboot.c linux/arch/i386/kernel/smpboot.c
--- linux.orig/arch/i386/kernel/smpboot.c	Fri Dec 21 17:41:53 2001
+++ linux/arch/i386/kernel/smpboot.c	Tue May 28 22:39:27 2002
@@ -213,7 +213,7 @@
  *		    ^---- (this multiplication can overflow)
  */
 
-static unsigned long long div64 (unsigned long long a, unsigned long b0)
+static unsigned long long __init div64 (unsigned long long a, unsigned long b0)
 {
 	unsigned int a1, a2;
 	unsigned long long res;
@@ -981,11 +981,14 @@
 {
 	int apicid, cpu, bit;
 
-        if (clustered_apic_mode) {
-                /* remap the 1st quad's 256k range for cross-quad I/O */
-                xquad_portio = ioremap (XQUAD_PORTIO_BASE, XQUAD_PORTIO_LEN);
-                printk("Cross quad port I/O vaddr 0x%08lx, len %08lx\n",
-                        (u_long) xquad_portio, (u_long) XQUAD_PORTIO_LEN);
+        if (clustered_apic_mode && (numnodes > 1)) {
+                printk("Remapping cross-quad port I/O for %d quads\n",
+			numnodes);
+                printk("xquad_portio vaddr 0x%08lx, len %08lx\n",
+                        (u_long) xquad_portio, 
+			(u_long) numnodes * XQUAD_PORTIO_LEN);
+                xquad_portio = ioremap (XQUAD_PORTIO_BASE, 
+			numnodes * XQUAD_PORTIO_LEN);
         }
 
 #ifdef CONFIG_MTRR
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/i386/kernel/traps.c linux/arch/i386/kernel/traps.c
--- linux.orig/arch/i386/kernel/traps.c	Sun Sep 30 19:26:08 2001
+++ linux/arch/i386/kernel/traps.c	Tue May 28 22:39:18 2002
@@ -237,6 +237,41 @@
 	printk("\n");
 }	
 
+static void handle_BUG(struct pt_regs *regs)
+{
+	unsigned short ud2;
+	unsigned short line;
+	char *file;
+	char c;
+	unsigned long eip;
+
+	if (regs->xcs & 3)
+		goto no_bug;		/* Not in kernel */
+
+	eip = regs->eip;
+
+	if (eip < PAGE_OFFSET)
+		goto no_bug;
+	if (__get_user(ud2, (unsigned short *)eip))
+		goto no_bug;
+	if (ud2 != 0x0b0f)
+		goto no_bug;
+	if (__get_user(line, (unsigned short *)(eip + 2)))
+		goto bug;
+	if (__get_user(file, (char **)(eip + 4)) ||
+		(unsigned long)file < PAGE_OFFSET || __get_user(c, file))
+		file = "<bad filename>";
+
+	printk("kernel BUG at %s:%d!\n", file, line);
+
+no_bug:
+	return;
+
+	/* Here we know it was a BUG but file-n-line is unavailable */
+bug:
+	printk("Kernel BUG\n");
+}
+
 spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
 
 void die(const char * str, struct pt_regs * regs, long err)
@@ -244,6 +279,7 @@
 	console_verbose();
 	spin_lock_irq(&die_lock);
 	bust_spinlocks(1);
+	handle_BUG(regs);
 	printk("%s: %04lx\n", str, err & 0xffff);
 	show_registers(regs);
 	bust_spinlocks(0);
@@ -505,6 +541,8 @@
 		 * allowing programs to debug themselves without the ptrace()
 		 * interface.
 		 */
+		if ((regs->xcs & 3) == 0)
+			goto clear_TF;
 		if ((tsk->ptrace & (PT_DTRACE|PT_PTRACED)) == PT_DTRACE)
 			goto clear_TF;
 	}
@@ -918,6 +956,10 @@
 #ifdef CONFIG_EISA
 	if (isa_readl(0x0FFFD9) == 'E'+('I'<<8)+('S'<<16)+('A'<<24))
 		EISA_bus = 1;
+#endif
+
+#ifdef CONFIG_X86_LOCAL_APIC
+	init_apic_mappings();
 #endif
 
 	set_trap_gate(0,&divide_error);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/i386/lib/mmx.c linux/arch/i386/lib/mmx.c
--- linux.orig/arch/i386/lib/mmx.c	Tue May 22 17:23:16 2001
+++ linux/arch/i386/lib/mmx.c	Tue May 28 22:39:28 2002
@@ -57,7 +57,7 @@
 		: : "r" (from) );
 		
 	
-	for(; i>0; i--)
+	for(; i>5; i--)
 	{
 		__asm__ __volatile__ (
 		"1:  prefetch 320(%0)\n"
@@ -85,6 +85,30 @@
 		"	.align 4\n"
 		"	.long 1b, 3b\n"
 		".previous"
+		: : "r" (from), "r" (to) : "memory");
+		from+=64;
+		to+=64;
+	}
+
+	for(; i>0; i--)
+	{
+		__asm__ __volatile__ (
+		"  movq (%0), %%mm0\n"
+		"  movq 8(%0), %%mm1\n"
+		"  movq 16(%0), %%mm2\n"
+		"  movq 24(%0), %%mm3\n"
+		"  movq %%mm0, (%1)\n"
+		"  movq %%mm1, 8(%1)\n"
+		"  movq %%mm2, 16(%1)\n"
+		"  movq %%mm3, 24(%1)\n"
+		"  movq 32(%0), %%mm0\n"
+		"  movq 40(%0), %%mm1\n"
+		"  movq 48(%0), %%mm2\n"
+		"  movq 56(%0), %%mm3\n"
+		"  movq %%mm0, 32(%1)\n"
+		"  movq %%mm1, 40(%1)\n"
+		"  movq %%mm2, 48(%1)\n"
+		"  movq %%mm3, 56(%1)\n"
 		: : "r" (from), "r" (to) : "memory");
 		from+=64;
 		to+=64;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/i386/math-emu/reg_add_sub.c linux/arch/i386/math-emu/reg_add_sub.c
--- linux.orig/arch/i386/math-emu/reg_add_sub.c	Wed Dec 10 01:57:09 1997
+++ linux/arch/i386/math-emu/reg_add_sub.c	Tue May 28 22:39:27 2002
@@ -140,7 +140,7 @@
   FPU_REG const *a, *b;
   FPU_REG *dest;
   u_char taga, tagb, signa, signb, saved_sign, sign;
-  int diff, tag, expa, expb, deststnr;
+  int diff, tag = 0, expa, expb, deststnr;
 
   a = &st(0);
   taga = FPU_gettag0();
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/i386/math-emu/reg_compare.c linux/arch/i386/math-emu/reg_compare.c
--- linux.orig/arch/i386/math-emu/reg_compare.c	Fri Apr  6 17:42:47 2001
+++ linux/arch/i386/math-emu/reg_compare.c	Tue May 28 22:39:21 2002
@@ -174,7 +174,7 @@
 /* This function requires that st(0) is not empty */
 int FPU_compare_st_data(FPU_REG const *loaded_data, u_char loaded_tag)
 {
-  int f, c;
+  int f = 0, c;
 
   c = compare(loaded_data, loaded_tag);
 
@@ -216,7 +216,7 @@
 
 static int compare_st_st(int nr)
 {
-  int f, c;
+  int f = 0, c;
   FPU_REG *st_ptr;
 
   if ( !NOT_EMPTY(0) || !NOT_EMPTY(nr) )
@@ -268,7 +268,7 @@
 
 static int compare_u_st_st(int nr)
 {
-  int f, c;
+  int f = 0, c;
   FPU_REG *st_ptr;
 
   if ( !NOT_EMPTY(0) || !NOT_EMPTY(nr) )
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/i386/math-emu/reg_divide.c linux/arch/i386/math-emu/reg_divide.c
--- linux.orig/arch/i386/math-emu/reg_divide.c	Fri Apr  6 17:42:47 2001
+++ linux/arch/i386/math-emu/reg_divide.c	Tue May 28 22:39:13 2002
@@ -203,4 +203,5 @@
     }
 #endif /* PARANOID */ 
 
+	return 0;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/i386/math-emu/reg_ld_str.c linux/arch/i386/math-emu/reg_ld_str.c
--- linux.orig/arch/i386/math-emu/reg_ld_str.c	Fri Apr  6 17:42:47 2001
+++ linux/arch/i386/math-emu/reg_ld_str.c	Tue May 28 22:39:17 2002
@@ -632,7 +632,7 @@
 /* Put a float into user memory */
 int FPU_store_single(FPU_REG *st0_ptr, u_char st0_tag, float *single)
 {
-  long templ;
+  long templ = 0;
   unsigned long increment = 0;     	/* avoid gcc warnings */
   int precision_loss;
   int exp;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/i386/math-emu/reg_mul.c linux/arch/i386/math-emu/reg_mul.c
--- linux.orig/arch/i386/math-emu/reg_mul.c	Fri Apr  6 17:42:47 2001
+++ linux/arch/i386/math-emu/reg_mul.c	Tue May 28 22:39:21 2002
@@ -128,4 +128,5 @@
     }
 #endif /* PARANOID */ 
 
+	return 0;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/i386/mm/fault.c linux/arch/i386/mm/fault.c
--- linux.orig/arch/i386/mm/fault.c	Mon Feb 25 19:37:53 2002
+++ linux/arch/i386/mm/fault.c	Tue May 28 22:39:12 2002
@@ -125,12 +125,6 @@
 	}
 }
 
-void do_BUG(const char *file, int line)
-{
-	bust_spinlocks(1);
-	printk("kernel BUG at %s:%d!\n", file, line);
-}
-
 asmlinkage void do_invalid_op(struct pt_regs *, unsigned long);
 extern unsigned long idt;
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/i386/mm/init.c linux/arch/i386/mm/init.c
--- linux.orig/arch/i386/mm/init.c	Fri Dec 21 17:41:53 2001
+++ linux/arch/i386/mm/init.c	Tue May 28 22:39:19 2002
@@ -128,7 +128,6 @@
 static inline void set_pte_phys (unsigned long vaddr,
 			unsigned long phys, pgprot_t flags)
 {
-	pgprot_t prot;
 	pgd_t *pgd;
 	pmd_t *pmd;
 	pte_t *pte;
@@ -144,10 +143,8 @@
 		return;
 	}
 	pte = pte_offset(pmd, vaddr);
-	if (pte_val(*pte))
-		pte_ERROR(*pte);
-	pgprot_val(prot) = pgprot_val(PAGE_KERNEL) | pgprot_val(flags);
-	set_pte(pte, mk_pte_phys(phys, prot));
+	/* <phys,flags> stored as-is, to permit clearing entries */
+	set_pte(pte, mk_pte_phys(phys, flags));
 
 	/*
 	 * It's enough to flush this one mapping.
@@ -462,8 +459,9 @@
 #ifdef CONFIG_HIGHMEM
 	highmem_start_page = mem_map + highstart_pfn;
 	max_mapnr = num_physpages = highend_pfn;
+	num_mappedpages = max_low_pfn;
 #else
-	max_mapnr = num_physpages = max_low_pfn;
+	max_mapnr = num_mappedpages = num_physpages = max_low_pfn;
 #endif
 	high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
 
@@ -505,7 +503,7 @@
 	datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
 	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
 
-	printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init, %ldk highmem)\n",
+	printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init, %ldk highmem)\n",
 		(unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
 		max_mapnr << (PAGE_SHIFT-10),
 		codesize >> 10,
@@ -569,14 +567,14 @@
 		free_page(addr);
 		totalram_pages++;
 	}
-	printk ("Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);
+	printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);
 }
 
 #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);
+		printk (KERN_INFO "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);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/i386/mm/ioremap.c linux/arch/i386/mm/ioremap.c
--- linux.orig/arch/i386/mm/ioremap.c	Tue Mar 20 16:13:33 2001
+++ linux/arch/i386/mm/ioremap.c	Tue May 28 22:39:20 2002
@@ -161,3 +161,68 @@
 	if (addr > high_memory)
 		return vfree((void *) (PAGE_MASK & (unsigned long) addr));
 }
+
+void __init *bt_ioremap(unsigned long phys_addr, unsigned long size)
+{
+	unsigned long offset, last_addr;
+	unsigned int nrpages;
+	enum fixed_addresses idx;
+
+	/* Don't allow wraparound or zero size */
+	last_addr = phys_addr + size - 1;
+	if (!size || last_addr < phys_addr)
+		return NULL;
+
+	/*
+	 * Don't remap the low PCI/ISA area, it's always mapped..
+	 */
+	if (phys_addr >= 0xA0000 && last_addr < 0x100000)
+		return phys_to_virt(phys_addr);
+
+	/*
+	 * Mappings have to be page-aligned
+	 */
+	offset = phys_addr & ~PAGE_MASK;
+	phys_addr &= PAGE_MASK;
+	size = PAGE_ALIGN(last_addr) - phys_addr;
+
+	/*
+	 * Mappings have to fit in the FIX_BTMAP area.
+	 */
+	nrpages = size >> PAGE_SHIFT;
+	if (nrpages > NR_FIX_BTMAPS)
+		return NULL;
+
+	/*
+	 * Ok, go for it..
+	 */
+	idx = FIX_BTMAP_BEGIN;
+	while (nrpages > 0) {
+		set_fixmap(idx, phys_addr);
+		phys_addr += PAGE_SIZE;
+		--idx;
+		--nrpages;
+	}
+	return (void*) (offset + fix_to_virt(FIX_BTMAP_BEGIN));
+}
+
+void __init bt_iounmap(void *addr, unsigned long size)
+{
+	unsigned long virt_addr;
+	unsigned long offset;
+	unsigned int nrpages;
+	enum fixed_addresses idx;
+
+	virt_addr = (unsigned long)addr;
+	if (virt_addr < fix_to_virt(FIX_BTMAP_BEGIN))
+		return;
+	offset = virt_addr & ~PAGE_MASK;
+	nrpages = PAGE_ALIGN(offset + size - 1) >> PAGE_SHIFT;
+
+	idx = FIX_BTMAP_BEGIN;
+	while (nrpages > 0) {
+		__set_fixmap(idx, 0, __pgprot(0));
+		--idx;
+		--nrpages;
+	}
+}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/Makefile linux/arch/ia64/Makefile
--- linux.orig/arch/ia64/Makefile	Fri Nov  9 22:26:17 2001
+++ linux/arch/ia64/Makefile	Tue May 28 22:39:14 2002
@@ -25,7 +25,7 @@
 GCC_VERSION=$(shell $(CROSS_COMPILE)$(HOSTCC) -v 2>&1 | fgrep 'gcc version' | cut -f3 -d' ' | cut -f1 -d'.')
 
 ifneq ($(GCC_VERSION),2)
-	CFLAGS += -frename-registers --param max-inline-insns=400
+	CFLAGS += -frename-registers --param max-inline-insns=2000
 endif
 
 ifeq ($(CONFIG_ITANIUM_BSTEP_SPECIFIC),y)
@@ -58,7 +58,7 @@
 	CFLAGS		+= -DBRINGUP
         SUBDIRS         :=      arch/$(ARCH)/sn/kernel	\
 				arch/$(ARCH)/sn/io	\
-				arch/$(ARCH)/sn/fprom	\
+				arch/$(ARCH)/sn/fakeprom	\
 				$(SUBDIRS)
         CORE_FILES      :=      arch/$(ARCH)/sn/kernel/sn.o	\
 				arch/$(ARCH)/sn/io/sgiio.o	\
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/config.in linux/arch/ia64/config.in
--- linux.orig/arch/ia64/config.in	Fri Nov  9 22:26:17 2001
+++ linux/arch/ia64/config.in	Tue May 28 22:39:28 2002
@@ -135,6 +135,7 @@
 source drivers/mtd/Config.in
 source drivers/pnp/Config.in
 source drivers/block/Config.in
+source drivers/ieee1394/Config.in
 source drivers/message/i2o/Config.in
 source drivers/md/Config.in
 
@@ -163,6 +164,10 @@
 fi
 endmenu
 
+if [ "$CONFIG_PCI" = "y" ]; then
+  source drivers/message/fusion/Config.in
+fi
+
 if [ "$CONFIG_IA64_HP_SIM" = "n" ]; then
 
 if [ "$CONFIG_NET" = "y" ]; then
@@ -244,7 +249,7 @@
   mainmenu_option next_comment
   comment 'Simulated drivers'
 
-  tristate 'Simulated Ethernet ' CONFIG_SIMETH
+  bool 'Simulated Ethernet ' CONFIG_SIMETH
   bool 'Simulated serial driver support' CONFIG_SIM_SERIAL
   if [ "$CONFIG_SCSI" != "n" ]; then
     bool 'Simulated SCSI disk' CONFIG_SCSI_SIM
@@ -266,9 +271,7 @@
    bool '  Disable VHPT' CONFIG_DISABLE_VHPT
    bool '  Magic SysRq key' CONFIG_MAGIC_SYSRQ
 
-# early printk is currently broken for SMP: the secondary processors get stuck...
-#   bool '  Early printk support (requires VGA!)' CONFIG_IA64_EARLY_PRINTK
-
+   bool '  Early printk support (requires VGA!)' CONFIG_IA64_EARLY_PRINTK
    bool '  Debug memory allocations' CONFIG_DEBUG_SLAB
    bool '  Spinlock debugging' CONFIG_DEBUG_SPINLOCK
    bool '  Turn on compare-and-exchange bug checking (slow!)' CONFIG_IA64_DEBUG_CMPXCHG
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/defconfig linux/arch/ia64/defconfig
--- linux.orig/arch/ia64/defconfig	Fri Nov  9 22:26:17 2001
+++ linux/arch/ia64/defconfig	Tue May 28 22:39:16 2002
@@ -299,6 +299,7 @@
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_NCR53C406A is not set
 # CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_NCR53C8XX is not set
 # CONFIG_SCSI_SYM53C8XX is not set
 # CONFIG_SCSI_PAS16 is not set
@@ -373,6 +374,7 @@
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
+# CONFIG_VIA_RHINE_MMIO is not set
 # CONFIG_WINBOND_840 is not set
 # CONFIG_NET_POCKET is not set
 
@@ -554,6 +556,9 @@
 # CONFIG_TUNER_3036 is not set
 # CONFIG_VIDEO_STRADIS is not set
 # CONFIG_VIDEO_ZORAN is not set
+# CONFIG_VIDEO_ZORAN_BUZ is not set
+# CONFIG_VIDEO_ZORAN_DC10 is not set
+# CONFIG_VIDEO_ZORAN_LML33 is not set
 # CONFIG_VIDEO_ZR36120 is not set
 # CONFIG_VIDEO_MEYE is not set
 
@@ -584,11 +589,15 @@
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_BFS_FS is not set
+CONFIG_EXT3_FS=m
+CONFIG_JBD=m
+CONFIG_JBD_DEBUG=y
 CONFIG_FAT_FS=y
 CONFIG_MSDOS_FS=y
 # CONFIG_UMSDOS_FS is not set
@@ -626,6 +635,7 @@
 # Network File Systems
 #
 # CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_ROOT_NFS is not set
@@ -874,6 +884,7 @@
 CONFIG_IA64_PRINT_HAZARDS=y
 # CONFIG_DISABLE_VHPT is not set
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_IA64_EARLY_PRINTK=y
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_IA64_DEBUG_CMPXCHG is not set
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/hp/hpsim_console.c linux/arch/ia64/hp/hpsim_console.c
--- linux.orig/arch/ia64/hp/hpsim_console.c	Thu Oct 12 21:20:48 2000
+++ linux/arch/ia64/hp/hpsim_console.c	Tue May 28 22:39:21 2002
@@ -24,14 +24,12 @@
 
 static int simcons_init (struct console *, char *);
 static void simcons_write (struct console *, const char *, unsigned);
-static int simcons_wait_key (struct console *);
 static kdev_t simcons_console_device (struct console *);
 
 struct console hpsim_cons = {
 	name:		"simcons",
 	write:		simcons_write,
 	device:		simcons_console_device,
-	wait_key:	simcons_wait_key,
 	setup:		simcons_init,
 	flags:		CON_PRINTBUFFER,
 	index:		-1,
@@ -54,17 +52,6 @@
 		if (ch == '\n')
 		  ia64_ssc('\r', 0, 0, 0, SSC_PUTCHAR);
 	}
-}
-
-static int
-simcons_wait_key (struct console *cons)
-{
-	char ch;
-
-	do {
-		ch = ia64_ssc(0, 0, 0, 0, SSC_GETCHAR);
-	} while (ch == '\0');
-	return ch;
 }
 
 static kdev_t
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/ia32/binfmt_elf32.c linux/arch/ia64/ia32/binfmt_elf32.c
--- linux.orig/arch/ia64/ia32/binfmt_elf32.c	Fri Nov  9 22:26:17 2001
+++ linux/arch/ia64/ia32/binfmt_elf32.c	Tue May 28 22:39:31 2002
@@ -142,10 +142,11 @@
 	/*
 	 * Setup GDTD.  Note: GDTD is the descrambled version of the pseudo-descriptor
 	 * format defined by Figure 3-11 "Pseudo-Descriptor Format" in the IA-32
-	 * architecture manual.
+	 * architecture manual. Also note that the only fields that are not ignored are
+	 * `base', `limit', 'G', `P' (must be 1) and `S' (must be 0).
 	 */
-	regs->r31 = IA32_SEG_UNSCRAMBLE(IA32_SEG_DESCRIPTOR(IA32_GDT_OFFSET, IA32_PAGE_SIZE - 1, 0,
-							    0, 0, 0, 0, 0, 0));
+	regs->r31 = IA32_SEG_UNSCRAMBLE(IA32_SEG_DESCRIPTOR(IA32_GDT_OFFSET, IA32_PAGE_SIZE - 1,
+							    0, 0, 0, 1, 0, 0, 0));
 	/* Setup the segment selectors */
 	regs->r16 = (__USER_DS << 16) | __USER_DS; /* ES == DS, GS, FS are zero */
 	regs->r17 = (__USER_DS << 16) | __USER_CS; /* SS, CS; ia32_load_state() sets TSS and LDT */
@@ -206,6 +207,7 @@
 	set_personality(PER_LINUX32);
 	current->thread.map_base  = IA32_PAGE_OFFSET/3;
 	current->thread.task_size = IA32_PAGE_OFFSET;	/* use what Linux/x86 uses... */
+	current->thread.flags |= IA64_THREAD_XSTACK;	/* data must be executable */
 	set_fs(USER_DS);				/* set addr limit for new TASK_SIZE */
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/ia32/ia32_entry.S linux/arch/ia64/ia32/ia32_entry.S
--- linux.orig/arch/ia64/ia32/ia32_entry.S	Fri Nov  9 22:26:17 2001
+++ linux/arch/ia64/ia32/ia32_entry.S	Tue May 28 22:39:13 2002
@@ -37,7 +37,7 @@
 	mov loc1=r16				// save ar.pfs across do_fork
 	.body
 	zxt4 out1=in1				// newsp
-	mov out3=0				// stacksize
+	mov out3=16				// stacksize (compensates for 16-byte scratch area)
 	adds out2=IA64_SWITCH_STACK_SIZE+16,sp	// out2 = &regs
 	zxt4 out0=in0				// out0 = clone_flags
 	br.call.sptk.many rp=do_fork
@@ -220,7 +220,7 @@
 	data8 sys32_pipe
 	data8 sys32_times
 	data8 sys32_ni_syscall	  /* old prof syscall holder */
-	data8 sys_brk		  /* 45 */
+	data8 sys32_brk		  /* 45 */
 	data8 sys_setgid	/* 16-bit version */
 	data8 sys_getgid	/* 16-bit version */
 	data8 sys32_signal
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/ia32/ia32_ioctl.c linux/arch/ia64/ia32/ia32_ioctl.c
--- linux.orig/arch/ia64/ia32/ia32_ioctl.c	Fri Nov  9 22:26:17 2001
+++ linux/arch/ia64/ia32/ia32_ioctl.c	Tue May 28 22:39:30 2002
@@ -79,6 +79,38 @@
 
 		      return ret;
 	      }
+		case IOCTL_NR(SIOCGIFCONF):
+		{
+			struct ifconf32 {
+				int		ifc_len;
+				unsigned int	ifc_ptr;
+			} ifconf32;
+			struct ifconf ifconf;
+			int i, n;
+			char *p32, *p64;
+			char buf[32];	/* sizeof IA32 ifreq structure */
+
+			if (copy_from_user(&ifconf32, P(arg), sizeof(ifconf32)))
+				return -EFAULT;
+			ifconf.ifc_len = ifconf32.ifc_len;
+			ifconf.ifc_req = P(ifconf32.ifc_ptr);
+			ret = DO_IOCTL(fd, SIOCGIFCONF, &ifconf);
+			ifconf32.ifc_len = ifconf.ifc_len;
+			if (copy_to_user(P(arg), &ifconf32, sizeof(ifconf32)))
+				return -EFAULT;
+			n = ifconf.ifc_len / sizeof(struct ifreq);
+			p32 = P(ifconf32.ifc_ptr);
+			p64 = P(ifconf32.ifc_ptr);
+			for (i = 0; i < n; i++) {
+				if (copy_from_user(buf, p64, sizeof(struct ifreq)))
+					return -EFAULT;
+				if (copy_to_user(p32, buf, sizeof(buf)))
+					return -EFAULT;
+				p32 += sizeof(buf);
+				p64 += sizeof(struct ifreq);
+			}
+			return ret;
+		}
 
 	      case IOCTL_NR(DRM_IOCTL_VERSION):
 	      {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/ia32/ia32_signal.c linux/arch/ia64/ia32/ia32_signal.c
--- linux.orig/arch/ia64/ia32/ia32_signal.c	Fri Nov  9 22:26:17 2001
+++ linux/arch/ia64/ia32/ia32_signal.c	Tue May 28 22:39:14 2002
@@ -522,6 +522,7 @@
 static int
 setup_frame_ia32 (int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs * regs)
 {
+	struct exec_domain *ed = current->exec_domain;
 	struct sigframe_ia32 *frame;
 	int err = 0;
 
@@ -530,12 +531,8 @@
 	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
 		goto give_sigsegv;
 
-	err |= __put_user((current->exec_domain
-			   && current->exec_domain->signal_invmap
-			   && sig < 32
-			   ? (int)(current->exec_domain->signal_invmap[sig])
-			   : sig),
-			  &frame->sig);
+	err |= __put_user((ed && ed->signal_invmap
+			   && sig < 32 ? (int)(ed->signal_invmap[sig]) : sig), &frame->sig);
 
 	err |= setup_sigcontext_ia32(&frame->sc, &frame->fpstate, regs, set->sig[0]);
 
@@ -590,6 +587,7 @@
 setup_rt_frame_ia32 (int sig, struct k_sigaction *ka, siginfo_t *info,
 		     sigset_t *set, struct pt_regs * regs)
 {
+	struct exec_domain *ed = current->exec_domain;
 	struct rt_sigframe_ia32 *frame;
 	int err = 0;
 
@@ -598,11 +596,8 @@
 	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
 		goto give_sigsegv;
 
-	err |= __put_user((current->exec_domain
-			   && current->exec_domain->signal_invmap
-			   && sig < 32
-			   ? current->exec_domain->signal_invmap[sig]
-			   : sig),
+	err |= __put_user((ed && ed->signal_invmap
+			   && sig < 32 ? ed->signal_invmap[sig] : sig),
 			  &frame->sig);
 	err |= __put_user((long)&frame->info, &frame->pinfo);
 	err |= __put_user((long)&frame->uc, &frame->puc);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/ia32/ia32_support.c linux/arch/ia64/ia32/ia32_support.c
--- linux.orig/arch/ia64/ia32/ia32_support.c	Fri Nov  9 22:26:17 2001
+++ linux/arch/ia64/ia32/ia32_support.c	Tue May 28 22:39:15 2002
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1999 Arun Sharma <arun.sharma@intel.com>
  * Copyright (C) 2000 Asit K. Mallick <asit.k.mallick@intel.com>
- * Copyright (C) 2001 Hewlett-Packard Co
+ * Copyright (C) 2001-2002 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *
  * 06/16/00	A. Mallick	added csd/ssd/tssd for ia32 thread context
@@ -153,10 +153,12 @@
 	/* We never change the TSS and LDT descriptors, so we can share them across all CPUs.  */
 	ldt_size = PAGE_ALIGN(IA32_LDT_ENTRIES*IA32_LDT_ENTRY_SIZE);
 	for (nr = 0; nr < NR_CPUS; ++nr) {
-		ia32_gdt[_TSS(nr)] = IA32_SEG_DESCRIPTOR(IA32_TSS_OFFSET, 235,
-							 0xb, 0, 3, 1, 1, 1, 0);
-		ia32_gdt[_LDT(nr)] = IA32_SEG_DESCRIPTOR(IA32_LDT_OFFSET, ldt_size - 1,
-							 0x2, 0, 3, 1, 1, 1, 0);
+		ia32_gdt[_TSS(nr) >> IA32_SEGSEL_INDEX_SHIFT]
+			= IA32_SEG_DESCRIPTOR(IA32_TSS_OFFSET, 235,
+					      0xb, 0, 3, 1, 1, 1, 0);
+		ia32_gdt[_LDT(nr) >> IA32_SEGSEL_INDEX_SHIFT]
+			= IA32_SEG_DESCRIPTOR(IA32_LDT_OFFSET, ldt_size - 1,
+					      0x2, 0, 3, 1, 1, 1, 0);
 	}
 }
 
@@ -172,6 +174,10 @@
 
 	siginfo.si_signo = SIGTRAP;
 	siginfo.si_errno = int_num;	/* XXX is it OK to abuse si_errno like this? */
+	siginfo.si_flags = 0;
+	siginfo.si_isr = 0;
+	siginfo.si_addr = 0;
+	siginfo.si_imm = 0;
 	siginfo.si_code = TRAP_BRKPT;
 	force_sig_info(SIGTRAP, &siginfo, current);
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/ia32/ia32_traps.c linux/arch/ia64/ia32/ia32_traps.c
--- linux.orig/arch/ia64/ia32/ia32_traps.c	Fri Nov  9 22:26:17 2001
+++ linux/arch/ia64/ia32/ia32_traps.c	Tue May 28 22:39:23 2002
@@ -2,7 +2,7 @@
  * IA-32 exception handlers
  *
  * Copyright (C) 2000 Asit K. Mallick <asit.k.mallick@intel.com>
- * Copyright (C) 2001 Hewlett-Packard Co
+ * Copyright (C) 2001-2002 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *
  * 06/16/00	A. Mallick	added siginfo for most cases (close to IA32)
@@ -40,7 +40,11 @@
 {
 	struct siginfo siginfo;
 
+	/* initialize these fields to avoid leaking kernel bits to user space: */
 	siginfo.si_errno = 0;
+	siginfo.si_flags = 0;
+	siginfo.si_isr = 0;
+	siginfo.si_imm = 0;
 	switch ((isr >> 16) & 0xff) {
 	      case 1:
 	      case 2:
@@ -103,6 +107,8 @@
 			 * and it will suffer the consequences since we won't be able to
 			 * fully reproduce the context of the exception
 			 */
+			siginfo.si_isr = isr;
+			siginfo.si_flags = __ISR_VALID;
 			switch(((~fcr) & (fsr & 0x3f)) | (fsr & 0x240)) {
 				case 0x000:
 				default:
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/ia32/sys_ia32.c linux/arch/ia64/ia32/sys_ia32.c
--- linux.orig/arch/ia64/ia32/sys_ia32.c	Fri Nov  9 22:26:17 2001
+++ linux/arch/ia64/ia32/sys_ia32.c	Tue May 28 22:39:15 2002
@@ -6,7 +6,7 @@
  * Copyright (C) 1999		Arun Sharma <arun.sharma@intel.com>
  * Copyright (C) 1997,1998	Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  * Copyright (C) 1997		David S. Miller (davem@caip.rutgers.edu)
- * Copyright (C) 2000-2001 Hewlett-Packard Co
+ * Copyright (C) 2000-2002 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *
  * These routines maintain argument size conversion between 32bit and 64bit
@@ -82,6 +82,7 @@
 
 /* forward declaration: */
 asmlinkage long sys32_mprotect (unsigned int, unsigned int, int);
+asmlinkage unsigned long sys_brk(unsigned long);
 
 /*
  * Anything that modifies or inspects ia32 user virtual memory must hold this semaphore
@@ -412,7 +413,7 @@
 			return -EINVAL;
 		}
 		if (!(prot & PROT_WRITE) && sys_mprotect(pstart, pend - pstart, prot) < 0)
-			return EINVAL;
+			return -EINVAL;
 	}
 	return start;
 }
@@ -2590,6 +2591,7 @@
 	      default:
 		return -EINVAL;
 	}
+	return -EINVAL;
 }
 
 /*
@@ -3807,6 +3809,19 @@
 	ret = sys_personality(personality);
 	if (ret == PER_LINUX32)
 		ret = PER_LINUX;
+	return ret;
+}
+
+asmlinkage unsigned long
+sys32_brk (unsigned int brk)
+{
+	unsigned long ret, obrk;
+	struct mm_struct *mm = current->mm;
+
+	obrk = mm->brk;
+	ret = sys_brk(brk);
+	if (ret < obrk)
+		clear_user((void *) ret, PAGE_ALIGN(ret) - ret);
 	return ret;
 }
 
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/kernel/Makefile linux/arch/ia64/kernel/Makefile
--- linux.orig/arch/ia64/kernel/Makefile	Fri Nov  9 22:26:17 2001
+++ linux/arch/ia64/kernel/Makefile	Tue May 28 22:39:27 2002
@@ -14,7 +14,7 @@
 export-objs := ia64_ksyms.o
 
 obj-y := acpi.o entry.o gate.o efi.o efi_stub.o ia64_ksyms.o irq.o irq_ia64.o irq_lsapic.o ivt.o \
-	 machvec.o pal.o process.o perfmon.o ptrace.o sal.o semaphore.o setup.o	\
+	 machvec.o pal.o process.o perfmon.o ptrace.o sal.o salinfo.o semaphore.o setup.o	 \
 	 signal.o sys_ia64.o traps.o time.o unaligned.o unwind.o
 obj-$(CONFIG_IA64_GENERIC) += iosapic.o
 obj-$(CONFIG_IA64_DIG) += iosapic.o
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/kernel/acpi.c linux/arch/ia64/kernel/acpi.c
--- linux.orig/arch/ia64/kernel/acpi.c	Fri Nov  9 22:26:17 2001
+++ linux/arch/ia64/kernel/acpi.c	Tue May 28 22:39:27 2002
@@ -401,7 +401,7 @@
 # ifdef CONFIG_ACPI
 	acpi_xsdt_t *xsdt;
 	acpi_desc_table_hdr_t *hdrp;
-	acpi_madt_t *madt;
+	acpi_madt_t *madt = NULL;
 	int tables, i;
 
 	if (strncmp(rsdp20->signature, ACPI_RSDP_SIG, ACPI_RSDP_SIG_LEN)) {
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/kernel/brl_emu.c linux/arch/ia64/kernel/brl_emu.c
--- linux.orig/arch/ia64/kernel/brl_emu.c	Thu Apr  5 19:51:47 2001
+++ linux/arch/ia64/kernel/brl_emu.c	Tue May 28 22:39:20 2002
@@ -2,6 +2,9 @@
  *  Emulation of the "brl" instruction for IA64 processors that
  *  don't support it in hardware.
  *  Author: Stephan Zeisset, Intel Corp. <Stephan.Zeisset@intel.com>
+ *
+ *    02/22/02	D. Mosberger	Clear si_flgs, si_isr, and si_imm to avoid
+ *				leaking kernel bits.
  */
 
 #include <linux/kernel.h>
@@ -195,6 +198,9 @@
 		printk("Woah! Unimplemented Instruction Address Trap!\n");
 		siginfo.si_signo = SIGILL;
 		siginfo.si_errno = 0;
+		siginfo.si_flags = 0;
+		siginfo.si_isr = 0;
+		siginfo.si_imm = 0;
 		siginfo.si_code = ILL_BADIADDR;
 		force_sig_info(SIGILL, &siginfo, current);
 	} else if (ia64_psr(regs)->tb) {
@@ -205,6 +211,10 @@
 		siginfo.si_signo = SIGTRAP;
 		siginfo.si_errno = 0;
 		siginfo.si_code = TRAP_BRANCH;
+		siginfo.si_flags = 0;
+		siginfo.si_isr = 0;
+		siginfo.si_addr = 0;
+		siginfo.si_imm = 0;
 		force_sig_info(SIGTRAP, &siginfo, current);
 	} else if (ia64_psr(regs)->ss) {
 		/*
@@ -214,6 +224,10 @@
 		siginfo.si_signo = SIGTRAP;
 		siginfo.si_errno = 0;
 		siginfo.si_code = TRAP_TRACE;
+		siginfo.si_flags = 0;
+		siginfo.si_isr = 0;
+		siginfo.si_addr = 0;
+		siginfo.si_imm = 0;
 		force_sig_info(SIGTRAP, &siginfo, current);
 	}
 	return rv;
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/kernel/efi.c linux/arch/ia64/kernel/efi.c
--- linux.orig/arch/ia64/kernel/efi.c	Fri Nov  9 22:26:17 2001
+++ linux/arch/ia64/kernel/efi.c	Tue May 28 22:39:14 2002
@@ -346,6 +346,9 @@
 		} else if (efi_guidcmp(config_tables[i].guid, SAL_SYSTEM_TABLE_GUID) == 0) {
 			efi.sal_systab = __va(config_tables[i].table);
 			printk(" SALsystab=0x%lx", config_tables[i].table);
+		} else if (efi_guidcmp(config_tables[i].guid, HCDP_TABLE_GUID) == 0) {
+			efi.hcdp = __va(config_tables[i].table);
+			printk(" HCDP=0x%lx", config_tables[i].table);
 		}
 	}
 	printk("\n");
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/kernel/efivars.c linux/arch/ia64/kernel/efivars.c
--- linux.orig/arch/ia64/kernel/efivars.c	Fri Dec 21 17:41:53 2001
+++ linux/arch/ia64/kernel/efivars.c	Tue May 28 22:39:27 2002
@@ -29,6 +29,11 @@
  *
  * Changelog:
  *
+ *  12 Feb 2002 - Matt Domsch <Matt_Domsch@dell.com>
+ *   use list_for_each_safe when deleting vars.
+ *   remove ifdef CONFIG_SMP around include <linux/smp.h>
+ *   v0.04 release to linux-ia64@linuxia64.org
+ *
  *  20 April 2001 - Matt Domsch <Matt_Domsch@dell.com>
  *   Moved vars from /proc/efi to /proc/efi/vars, and made
  *   efi.c own the /proc/efi directory.
@@ -56,18 +61,16 @@
 #include <linux/sched.h>		/* for capable() */
 #include <linux/mm.h>
 #include <linux/module.h>
+#include <linux/smp.h>
 
 #include <asm/efi.h>
 #include <asm/uaccess.h>
-#ifdef CONFIG_SMP
-#include <linux/smp.h>
-#endif
 
 MODULE_AUTHOR("Matt Domsch <Matt_Domsch@Dell.com>");
 MODULE_DESCRIPTION("/proc interface to EFI Variables");
 MODULE_LICENSE("GPL");
 
-#define EFIVARS_VERSION "0.03 2001-Apr-20"
+#define EFIVARS_VERSION "0.04 2002-Feb-12"
 
 static int
 efivar_read(char *page, char **start, off_t off,
@@ -265,7 +268,7 @@
 {
 	unsigned long strsize1, strsize2;
 	int found=0;
-	struct list_head *pos;
+	struct list_head *pos, *n;
 	unsigned long size = sizeof(efi_variable_t);
 	efi_status_t status;
 	efivar_entry_t *efivar = data, *search_efivar = NULL;
@@ -297,7 +300,7 @@
 	   This allows any properly formatted data structure to
 	   be written to any of the files in /proc/efi/vars and it will work.
 	*/
-	list_for_each(pos, &efivar_list) {
+	list_for_each_safe(pos, n, &efivar_list) {
 		search_efivar = efivar_entry(pos);
 		strsize1 = utf8_strsize(search_efivar->var.VariableName, 1024);
 		strsize2 = utf8_strsize(var_data->VariableName, 1024);
@@ -413,12 +416,12 @@
 static void __exit
 efivars_exit(void)
 {
-	struct list_head *pos;
+	struct list_head *pos, *n;
 	efivar_entry_t *efivar;
 
 	spin_lock(&efivars_lock);
 
-	list_for_each(pos, &efivar_list) {
+	list_for_each_safe(pos, n, &efivar_list) {
 		efivar = efivar_entry(pos);
 		remove_proc_entry(efivar->entry->name, efi_vars_dir);
 		list_del(&efivar->list);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/kernel/entry.S linux/arch/ia64/kernel/entry.S
--- linux.orig/arch/ia64/kernel/entry.S	Fri Nov  9 22:26:17 2001
+++ linux/arch/ia64/kernel/entry.S	Tue May 28 22:39:20 2002
@@ -115,7 +115,7 @@
 	mov loc1=r16				// save ar.pfs across do_fork
 	.body
 	mov out1=in1
-	mov out3=0
+	mov out3=16				// stacksize (compensates for 16-byte scratch area)
 	adds out2=IA64_SWITCH_STACK_SIZE+16,sp	// out2 = &regs
 	mov out0=in0				// out0 = clone_flags
 	br.call.sptk.many rp=do_fork
@@ -521,35 +521,38 @@
 	;;
 	mov.ret.sptk rp=r14,.restart
 .restart:
+	// need_resched and signals atomic test
+(pUser)	rsm psr.i
 	adds r17=IA64_TASK_NEED_RESCHED_OFFSET,r13
 	adds r18=IA64_TASK_SIGPENDING_OFFSET,r13
 #ifdef CONFIG_PERFMON
-	adds r19=IA64_TASK_PFM_MUST_BLOCK_OFFSET,r13
+	adds r19=IA64_TASK_PFM_OVFL_BLOCK_RESET_OFFSET,r13
 #endif
 	;;
 #ifdef CONFIG_PERFMON
-(pUser)	ld8 r19=[r19]				// load current->thread.pfm_must_block
+(pUser)	ld8 r19=[r19]				// load current->thread.pfm_ovfl_block_reset
 #endif
 (pUser)	ld8 r17=[r17]				// load current->need_resched
 (pUser)	ld4 r18=[r18]				// load current->sigpending
 	;;
 #ifdef CONFIG_PERFMON
-(pUser)	cmp.ne.unc p9,p0=r19,r0			// current->thread.pfm_must_block != 0?
+(pUser)	cmp.ne.unc p9,p0=r19,r0			// current->thread.pfm_ovfl_block_reset != 0?
 #endif
 (pUser)	cmp.ne.unc p7,p0=r17,r0			// current->need_resched != 0?
 (pUser)	cmp.ne.unc p8,p0=r18,r0			// current->sigpending != 0?
 	;;
-	adds r2=PT(R8)+16,r12
-	adds r3=PT(R9)+16,r12
 #ifdef CONFIG_PERFMON
-(p9)	br.call.spnt.many b7=pfm_block_on_overflow
+(p9)	br.call.spnt.many b7=pfm_ovfl_block_reset
 #endif
 #if __GNUC__ < 3
 (p7)	br.call.spnt.many b7=invoke_schedule
 #else
 (p7)	br.call.spnt.many b7=schedule
 #endif
-(p8)	br.call.spnt.many b7=handle_signal_delivery	// check & deliver pending signals
+(p8)	br.call.spnt.many rp=handle_signal_delivery	// check & deliver pending signals (once)
+	;;
+.ret9:	adds r2=PT(R8)+16,r12
+	adds r3=PT(R9)+16,r12
 	;;
 	// start restoring the state saved on the kernel stack (struct pt_regs):
 	ld8.fill r8=[r2],16
@@ -582,7 +585,7 @@
 	ld8.fill r30=[r2],16
 	ld8.fill r31=[r3],16
 	;;
-	rsm psr.i | psr.ic	// initiate turning off of interrupts & interruption collection
+	rsm psr.i | psr.ic	// initiate turning off of interrupt and interruption collection
 	invala			// invalidate ALAT
 	;;
 	ld8 r1=[r2],16		// ar.ccv
@@ -601,7 +604,7 @@
 	mov ar.fpsr=r13
 	mov b0=r14
 	;;
-	srlz.i			// ensure interrupts & interruption collection are off
+	srlz.i			// ensure interruption collection is off
 	mov b7=r15
 	;;
 	bsw.0			// switch back to bank 0
@@ -1142,7 +1145,7 @@
 	data8 ia64_ni_syscall
 	data8 ia64_ni_syscall
 	data8 ia64_ni_syscall
-	data8 ia64_ni_syscall
+	data8 sys_tkill
 	data8 ia64_ni_syscall			// 1230
 	data8 ia64_ni_syscall
 	data8 ia64_ni_syscall
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/kernel/gate.S linux/arch/ia64/kernel/gate.S
--- linux.orig/arch/ia64/kernel/gate.S	Fri Nov  9 22:26:17 2001
+++ linux/arch/ia64/kernel/gate.S	Tue May 28 22:39:21 2002
@@ -90,7 +90,7 @@
 (p8)	br.cond.spnt setup_rbs		// yup -> (clobbers r14, r15, and r16)
 back_from_setup_rbs:
 
-	.save ar.pfs, r8
+	.spillreg ar.pfs, r8
 	alloc r8=ar.pfs,0,0,3,0		// get CFM0, EC0, and CPL0 into r8
 	ld8 out0=[base0],16		// load arg0 (signum)
 	adds base1=(ARG1_OFF-(RBS_BASE_OFF+SIGCONTEXT_OFF)),base1
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/kernel/head.S linux/arch/ia64/kernel/head.S
--- linux.orig/arch/ia64/kernel/head.S	Fri Nov  9 22:26:17 2001
+++ linux/arch/ia64/kernel/head.S	Tue May 28 22:39:29 2002
@@ -180,10 +180,12 @@
 	.rodata
 alive_msg:
 	stringz "I'm alive and well\n"
+alive_msg_end:
 	.previous
 
 	alloc r2=ar.pfs,0,0,2,0
 	movl out0=alive_msg
+	movl out1=alive_msg_end-alive_msg-1
 	;;
 	br.call.sptk.many rp=early_printk
 1:	// force new bundle
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/kernel/ia64_ksyms.c linux/arch/ia64/kernel/ia64_ksyms.c
--- linux.orig/arch/ia64/kernel/ia64_ksyms.c	Fri Nov  9 22:26:17 2001
+++ linux/arch/ia64/kernel/ia64_ksyms.c	Tue May 28 22:39:26 2002
@@ -24,6 +24,7 @@
 EXPORT_SYMBOL(strrchr);
 EXPORT_SYMBOL(strstr);
 EXPORT_SYMBOL(strtok);
+EXPORT_SYMBOL(strpbrk);
 
 #include <linux/irq.h>
 EXPORT_SYMBOL(isa_irq_to_vector_map);
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/kernel/iosapic.c linux/arch/ia64/kernel/iosapic.c
--- linux.orig/arch/ia64/kernel/iosapic.c	Fri Nov  9 22:26:17 2001
+++ linux/arch/ia64/kernel/iosapic.c	Tue May 28 22:39:27 2002
@@ -3,8 +3,9 @@
  *
  * Copyright (C) 1999 Intel Corp.
  * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
- * Copyright (C) 1999-2000 Hewlett-Packard Co.
- * Copyright (C) 1999-2000 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 2000-2002 J.I. Lee <jung-ik.lee@intel.com>
+ * Copyright (C) 1999-2000, 2002 Hewlett-Packard Co.
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
  * Copyright (C) 1999 VA Linux Systems
  * Copyright (C) 1999,2000 Walt Drummond <drummond@valinux.com>
  *
@@ -15,6 +16,12 @@
  *				PCI to vector mapping, shared PCI interrupts.
  * 00/10/27	D. Mosberger	Document things a bit more to make them more understandable.
  *				Clean up much of the old IOSAPIC cruft.
+ * 01/07/27	J.I. Lee	PCI irq routing, Platform/Legacy interrupts and fixes for
+ *				ACPI S5(SoftOff) support.
+ * 02/01/23	J.I. Lee	iosapic pgm fixes for PCI irq routing from _PRT
+ * 02/01/07     E. Focht        <efocht@ess.nec.de> Redirectable interrupt vectors in
+ *                              iosapic_set_affinity(), initializations for
+ *                              /proc/irq/#/smp_affinity
  */
 /*
  * Here is what the interrupt logic between a PCI device and the CPU looks like:
@@ -63,6 +70,7 @@
 
 
 #undef DEBUG_IRQ_ROUTING
+#undef	OVERRIDE_DEBUG
 
 static spinlock_t iosapic_lock = SPIN_LOCK_UNLOCKED;
 
@@ -88,7 +96,7 @@
  * Translate IOSAPIC irq number to the corresponding IA-64 interrupt vector.  If no
  * entry exists, return -1.
  */
-static int
+int
 iosapic_irq_to_vector (int irq)
 {
 	int vector;
@@ -121,6 +129,7 @@
 	u32 low32, high32;
 	char *addr;
 	int pin;
+	char redir;
 
 	pin = iosapic_irq[vector].pin;
 	if (pin < 0)
@@ -131,6 +140,11 @@
 	trigger = iosapic_irq[vector].trigger;
 	dmode   = iosapic_irq[vector].dmode;
 
+	redir = (dmode == IOSAPIC_LOWEST_PRIORITY) ? 1 : 0;
+#ifdef CONFIG_SMP
+	set_irq_affinity_info(vector, (int)(dest & 0xffff), redir);
+#endif
+
 	low32 = ((pol << IOSAPIC_POLARITY_SHIFT) |
 		 (trigger << IOSAPIC_TRIGGER_SHIFT) |
 		 (dmode << IOSAPIC_DELIVERY_SHIFT) |
@@ -211,6 +225,7 @@
 	u32 high32, low32;
 	int dest, pin;
 	char *addr;
+	int redir = (irq & (1<<31)) ? 1 : 0;
 
 	mask &= (1UL << smp_num_cpus) - 1;
 
@@ -225,6 +240,8 @@
 	if (pin < 0)
 		return;			/* not an IOSAPIC interrupt */
 
+	set_irq_affinity_info(irq,dest,redir);
+
 	/* dest contains both id and eid */
 	high32 = dest << IOSAPIC_DEST_SHIFT;
 
@@ -234,9 +251,13 @@
 		writel(IOSAPIC_RTE_LOW(pin), addr + IOSAPIC_REG_SELECT);
 		low32 = readl(addr + IOSAPIC_WINDOW);
 
-		/* change delivery mode to fixed */
 		low32 &= ~(7 << IOSAPIC_DELIVERY_SHIFT);
-		low32 |= (IOSAPIC_FIXED << IOSAPIC_DELIVERY_SHIFT);
+		if (redir)
+		        /* change delivery mode to lowest priority */
+			low32 |= (IOSAPIC_LOWEST_PRIORITY << IOSAPIC_DELIVERY_SHIFT);
+		else
+		        /* change delivery mode to fixed */
+			low32 |= (IOSAPIC_FIXED << IOSAPIC_DELIVERY_SHIFT);
 
 		writel(IOSAPIC_RTE_HIGH(pin), addr + IOSAPIC_REG_SELECT);
 		writel(high32, addr + IOSAPIC_WINDOW);
@@ -343,29 +364,64 @@
 }
 
 /*
- * ACPI can describe IOSAPIC interrupts via static tables and namespace
- * methods.  This provides an interface to register those interrupts and
- * program the IOSAPIC RTE.
+ * if the given vector is already owned by other,
+ *  assign a new vector for the other and make the vector available
  */
-int
-iosapic_register_irq (u32 global_vector, unsigned long polarity, unsigned long
-                      edge_triggered, u32 base_irq, char *iosapic_address)
+static void
+iosapic_reassign_vector (int vector)
+{
+	int new_vector;
+
+	if (iosapic_irq[vector].pin >= 0 || iosapic_irq[vector].addr
+	    || iosapic_irq[vector].base_irq || iosapic_irq[vector].dmode
+	    || iosapic_irq[vector].polarity || iosapic_irq[vector].trigger)
+	{
+		new_vector = ia64_alloc_irq();
+		printk("Reassigning Vector 0x%x to 0x%x\n", vector, new_vector);
+		memcpy (&iosapic_irq[new_vector], &iosapic_irq[vector],
+			sizeof(struct iosapic_irq));
+		memset (&iosapic_irq[vector], 0, sizeof(struct iosapic_irq));
+		iosapic_irq[vector].pin = -1;
+	}
+}
+
+static void
+register_irq (u32 global_vector, int vector, int pin, unsigned char delivery,
+	      unsigned long polarity, unsigned long edge_triggered,
+	      u32 base_irq, char *iosapic_address)
 {
 	irq_desc_t *idesc;
 	struct hw_interrupt_type *irq_type;
-	int vector;
 
-	vector = iosapic_irq_to_vector(global_vector);
-	if (vector < 0)
-		vector = ia64_alloc_irq();
-
-	/* fill in information from this vector's IOSAPIC */
-	iosapic_irq[vector].addr = iosapic_address;
-	iosapic_irq[vector].base_irq = base_irq;
-	iosapic_irq[vector].pin	= global_vector - iosapic_irq[vector].base_irq;
+	iosapic_irq[vector].pin	= pin;
 	iosapic_irq[vector].polarity = polarity ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW;
-	iosapic_irq[vector].dmode    = IOSAPIC_LOWEST_PRIORITY;
+	iosapic_irq[vector].dmode    = delivery;
 
+	/*
+	 * In override, it does not provide addr/base_irq.  global_vector is enough to
+	 * locate iosapic addr, base_irq and pin by examining base_irq and max_pin of
+	 * registered iosapics (tbd)
+	 */
+#ifndef	OVERRIDE_DEBUG
+	if (iosapic_address) {
+		iosapic_irq[vector].addr = iosapic_address;
+		iosapic_irq[vector].base_irq = base_irq;
+	}
+#else
+	if (iosapic_address) {
+		if (iosapic_irq[vector].addr && (iosapic_irq[vector].addr != iosapic_address))
+			printk("WARN: register_irq: diff IOSAPIC ADDRESS for gv %x, v %x\n",
+			       global_vector, vector);
+		iosapic_irq[vector].addr = iosapic_address;
+		if (iosapic_irq[vector].base_irq && (iosapic_irq[vector].base_irq != base_irq)) {
+			printk("WARN: register_irq: diff BASE IRQ %x for gv %x, v %x\n",
+			       base_irq, global_vector, vector);
+		}
+		iosapic_irq[vector].base_irq = base_irq;
+	} else if (!iosapic_irq[vector].addr)
+		printk("WARN: register_irq: invalid override for gv %x, v %x\n",
+		       global_vector, vector);
+#endif
 	if (edge_triggered) {
 		iosapic_irq[vector].trigger = IOSAPIC_EDGE;
 		irq_type = &irq_type_iosapic_edge;
@@ -377,12 +433,32 @@
 	idesc = irq_desc(vector);
 	if (idesc->handler != irq_type) {
 		if (idesc->handler != &no_irq_type)
-			printk("iosapic_register_irq(): changing vector 0x%02x from"
+			printk("register_irq(): changing vector 0x%02x from "
 			       "%s to %s\n", vector, idesc->handler->typename, irq_type->typename);
 		idesc->handler = irq_type;
 	}
+}
+
+/*
+ * ACPI can describe IOSAPIC interrupts via static tables and namespace
+ * methods.  This provides an interface to register those interrupts and
+ * program the IOSAPIC RTE.
+ */
+int
+iosapic_register_irq (u32 global_vector, unsigned long polarity, unsigned long
+                      edge_triggered, u32 base_irq, char *iosapic_address)
+{
+	int vector;
 
-	printk("IOSAPIC %x(%s,%s) -> Vector %x\n", global_vector,
+	vector = iosapic_irq_to_vector(global_vector);
+	if (vector < 0)
+		vector = ia64_alloc_irq();
+
+	register_irq (global_vector, vector, global_vector - base_irq,
+			IOSAPIC_LOWEST_PRIORITY, polarity, edge_triggered,
+			base_irq, iosapic_address);
+
+	printk("IOSAPIC 0x%x(%s,%s) -> Vector 0x%x\n", global_vector,
 	       (polarity ? "high" : "low"), (edge_triggered ? "edge" : "level"), vector);
 
 	/* program the IOSAPIC routing table */
@@ -395,51 +471,40 @@
  * Note that the irq_base and IOSAPIC address must be set in iosapic_init().
  */
 int
-iosapic_register_platform_irq (u32 int_type, u32 global_vector, u32 iosapic_vector,
-			       u16 eid, u16 id, unsigned long polarity,
+iosapic_register_platform_irq (u32 int_type, u32 global_vector,
+			       u32 iosapic_vector, u16 eid, u16 id, unsigned long polarity,
 			       unsigned long edge_triggered, u32 base_irq, char *iosapic_address)
 {
-	struct hw_interrupt_type *irq_type;
-	irq_desc_t *idesc;
+	unsigned char delivery;
 	int vector;
 
 	switch (int_type) {
-	      case ACPI20_ENTRY_PIS_CPEI:
+	case ACPI20_ENTRY_PIS_PMI:
+		vector = iosapic_vector;
+		/*
+		 * since PMI vector is alloc'd by FW(ACPI) not by kernel,
+		 * we need to make sure the vector is available
+		 */
+		iosapic_reassign_vector(vector);
+		delivery = IOSAPIC_PMI;
+		break;
+	case ACPI20_ENTRY_PIS_CPEI:
 		vector = IA64_PCE_VECTOR;
-		iosapic_irq[vector].dmode = IOSAPIC_LOWEST_PRIORITY;
+		delivery = IOSAPIC_LOWEST_PRIORITY;
 		break;
-	      case ACPI20_ENTRY_PIS_INIT:
+	case ACPI20_ENTRY_PIS_INIT:
 		vector = ia64_alloc_irq();
-		iosapic_irq[vector].dmode = IOSAPIC_INIT;
+		delivery = IOSAPIC_INIT;
 		break;
-	      default:
+	default:
 		printk("iosapic_register_platform_irq(): invalid int type\n");
 		return -1;
 	}
 
-	/* fill in information from this vector's IOSAPIC */
-	iosapic_irq[vector].addr = iosapic_address;
-	iosapic_irq[vector].base_irq = base_irq;
-	iosapic_irq[vector].pin	= global_vector - iosapic_irq[vector].base_irq;
-	iosapic_irq[vector].polarity = polarity ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW;
-
-	if (edge_triggered) {
-		iosapic_irq[vector].trigger = IOSAPIC_EDGE;
-		irq_type = &irq_type_iosapic_edge;
-	} else {
-		iosapic_irq[vector].trigger = IOSAPIC_LEVEL;
-		irq_type = &irq_type_iosapic_level;
-	}
-
-	idesc = irq_desc(vector);
-	if (idesc->handler != irq_type) {
-		if (idesc->handler != &no_irq_type)
-			printk("iosapic_register_platform_irq(): changing vector 0x%02x from"
-			       "%s to %s\n", vector, idesc->handler->typename, irq_type->typename);
-		idesc->handler = irq_type;
-	}
+	register_irq(global_vector, vector, global_vector - base_irq, delivery, polarity,
+		     edge_triggered, base_irq, iosapic_address);
 
-	printk("PLATFORM int %x: IOSAPIC %x(%s,%s) -> Vector %x CPU %.02u:%.02u\n",
+	printk("PLATFORM int 0x%x: IOSAPIC 0x%x(%s,%s) -> Vector 0x%x CPU %.02u:%.02u\n",
 	       int_type, global_vector, (polarity ? "high" : "low"),
 	       (edge_triggered ? "edge" : "level"), vector, eid, id);
 
@@ -450,15 +515,18 @@
 
 
 /*
- * ACPI calls this when it finds an entry for a legacy ISA interrupt.  Note that the
- * irq_base and IOSAPIC address must be set in iosapic_init().
+ * ACPI calls this when it finds an entry for a legacy ISA interrupt.
+ * Note that the irq_base and IOSAPIC address must be set in iosapic_init().
  */
 void
 iosapic_register_legacy_irq (unsigned long irq,
 			     unsigned long pin, unsigned long polarity,
 			     unsigned long edge_triggered)
 {
-	unsigned int vector = isa_irq_to_vector(irq);
+	int vector = isa_irq_to_vector(irq);
+
+	register_irq(irq, vector, (int)pin, IOSAPIC_LOWEST_PRIORITY, polarity, edge_triggered,
+		     0, NULL);		/* ignored for override */
 
 #ifdef DEBUG_IRQ_ROUTING
 	printk("ISA: IRQ %u -> IOSAPIC irq 0x%02x (%s, %s) -> vector %02x\n",
@@ -467,18 +535,14 @@
 	       vector);
 #endif
 
-	iosapic_irq[vector].pin = pin;
-	iosapic_irq[vector].dmode = IOSAPIC_LOWEST_PRIORITY;
-	iosapic_irq[vector].polarity = polarity ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW;
-	iosapic_irq[vector].trigger = edge_triggered ? IOSAPIC_EDGE : IOSAPIC_LEVEL;
+	/* program the IOSAPIC routing table */
+	set_rte(vector, (ia64_get_lid() >> 16) & 0xffff);
 }
 
 void __init
 iosapic_init (unsigned long phys_addr, unsigned int base_irq, int pcat_compat)
 {
-	struct hw_interrupt_type *irq_type;
-	int i, irq, max_pin, vector;
-	irq_desc_t *idesc;
+	int i, irq, max_pin, vector, pin;
 	unsigned int ver;
 	char *addr;
 	static int first_time = 1;
@@ -496,7 +560,6 @@
 	}
 
 	addr = ioremap(phys_addr, 0);
-
 	ver = iosapic_version(addr);
 	max_pin = (ver >> 16) & 0xff;
 
@@ -511,27 +574,18 @@
 		 */
 		for (irq = 0; irq < 16; ++irq) {
 			vector = isa_irq_to_vector(irq);
-			iosapic_irq[vector].addr = addr;
-			iosapic_irq[vector].base_irq = 0;
-			if (iosapic_irq[vector].pin == -1)
-				iosapic_irq[vector].pin = irq;
-			iosapic_irq[vector].dmode = IOSAPIC_LOWEST_PRIORITY;
-			iosapic_irq[vector].trigger  = IOSAPIC_EDGE;
-			iosapic_irq[vector].polarity = IOSAPIC_POL_HIGH;
+			if ((pin = iosapic_irq[vector].pin) == -1)
+				pin = irq;
+
+			register_irq(irq, vector, pin,
+				     /* IOSAPIC_POL_HIGH, IOSAPIC_EDGE */
+				     IOSAPIC_LOWEST_PRIORITY, 1, 1, base_irq, addr);
+
 #ifdef DEBUG_IRQ_ROUTING
 			printk("ISA: IRQ %u -> IOSAPIC irq 0x%02x (high, edge) -> vector 0x%02x\n",
 			       irq, iosapic_irq[vector].base_irq + iosapic_irq[vector].pin,
 			       vector);
 #endif
-			irq_type = &irq_type_iosapic_edge;
-			idesc = irq_desc(vector);
-			if (idesc->handler != irq_type) {
-				if (idesc->handler != &no_irq_type)
-					printk("iosapic_init: changing vector 0x%02x from %s to "
-					       "%s\n", irq, idesc->handler->typename,
-					       irq_type->typename);
-				idesc->handler = irq_type;
-			}
 
 			/* program the IOSAPIC routing table: */
 			set_rte(vector, (ia64_get_lid() >> 16) & 0xffff);
@@ -540,7 +594,7 @@
 	for (i = 0; i < pci_irq.num_routes; i++) {
 		irq = pci_irq.route[i].irq;
 
-		if ((unsigned) (irq - base_irq) > max_pin)
+		if ((irq < (int)base_irq) || (irq > (int)(base_irq + max_pin)))
 			/* the interrupt route is for another controller... */
 			continue;
 
@@ -553,29 +607,18 @@
 				vector = ia64_alloc_irq();
 		}
 
-		iosapic_irq[vector].addr     = addr;
-		iosapic_irq[vector].base_irq = base_irq;
-		iosapic_irq[vector].pin	     = (irq - base_irq);
-		iosapic_irq[vector].dmode    = IOSAPIC_LOWEST_PRIORITY;
-		iosapic_irq[vector].trigger  = IOSAPIC_LEVEL;
-		iosapic_irq[vector].polarity = IOSAPIC_POL_LOW;
+		register_irq(irq, vector, irq - base_irq,
+			     /* IOSAPIC_POL_LOW, IOSAPIC_LEVEL */
+			     IOSAPIC_LOWEST_PRIORITY, 0, 0, base_irq, addr);
 
 # ifdef DEBUG_IRQ_ROUTING
 		printk("PCI: (B%d,I%d,P%d) -> IOSAPIC irq 0x%02x -> vector 0x%02x\n",
 		       pci_irq.route[i].bus, pci_irq.route[i].pci_id>>16, pci_irq.route[i].pin,
 		       iosapic_irq[vector].base_irq + iosapic_irq[vector].pin, vector);
 # endif
-		irq_type = &irq_type_iosapic_level;
-		idesc = irq_desc(vector);
-		if (idesc->handler != irq_type){
-			if (idesc->handler != &no_irq_type)
-				printk("iosapic_init: changing vector 0x%02x from %s to %s\n",
-				       vector, idesc->handler->typename, irq_type->typename);
-			idesc->handler = irq_type;
-		}
 
-		/* program the IOSAPIC routing table: */
-		set_rte(vector, (ia64_get_lid() >> 16) & 0xffff);
+			/* program the IOSAPIC routing table: */
+			set_rte(vector, (ia64_get_lid() >> 16) & 0xffff);
 	}
 }
 
@@ -585,6 +628,8 @@
 	struct	pci_dev	*dev;
 	unsigned char pin;
 	int vector;
+	struct hw_interrupt_type *irq_type;
+	irq_desc_t *idesc;
 
 	if (phase != 1)
 		return;
@@ -611,19 +656,28 @@
 				if (vector >= 0)
 					printk(KERN_WARNING
 					       "PCI: using PPB(B%d,I%d,P%d) to get vector %02x\n",
-					       bridge->bus->number, PCI_SLOT(bridge->devfn),
+					       dev->bus->number, PCI_SLOT(dev->devfn),
 					       pin, vector);
 				else
 					printk(KERN_WARNING
-					       "PCI: Couldn't map irq for (B%d,I%d,P%d)o\n",
-					       bridge->bus->number, PCI_SLOT(bridge->devfn),
-					       pin);
+					       "PCI: Couldn't map irq for (B%d,I%d,P%d)\n",
+					       dev->bus->number, PCI_SLOT(dev->devfn), pin);
 			}
 			if (vector >= 0) {
 				printk("PCI->APIC IRQ transform: (B%d,I%d,P%d) -> 0x%02x\n",
 				       dev->bus->number, PCI_SLOT(dev->devfn), pin, vector);
 				dev->irq = vector;
 
+				irq_type = &irq_type_iosapic_level;
+				idesc = irq_desc(vector);
+				if (idesc->handler != irq_type){
+					if (idesc->handler != &no_irq_type)
+						printk("iosapic_pci_fixup: changing vector 0x%02x "
+						       "from %s to %s\n", vector,
+						       idesc->handler->typename,
+						       irq_type->typename);
+					idesc->handler = irq_type;
+				}
 #ifdef CONFIG_SMP
 				/*
 				 * For platforms that do not support interrupt redirect
@@ -638,7 +692,16 @@
 					cpu_index++;
 					if (cpu_index >= smp_num_cpus)
 						cpu_index = 0;
+				} else {
+					/*
+					 * Direct the interrupt vector to the current cpu,
+					 * platform redirection will distribute them.
+					 */
+					set_rte(vector, (ia64_get_lid() >> 16) & 0xffff);
 				}
+#else
+				/* direct the interrupt vector to the running cpu id */
+				set_rte(vector, (ia64_get_lid() >> 16) & 0xffff);
 #endif
 			}
 		}
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/kernel/irq.c linux/arch/ia64/kernel/irq.c
--- linux.orig/arch/ia64/kernel/irq.c	Fri Nov  9 22:26:17 2001
+++ linux/arch/ia64/kernel/irq.c	Tue May 28 22:39:23 2002
@@ -287,10 +287,11 @@
 		 * already executing in one..
 		 */
 		if (!irqs_running())
-			if (local_bh_count() || !spin_is_locked(&global_bh_lock))
+			if (really_local_bh_count() || !spin_is_locked(&global_bh_lock))
 				break;
 
 		/* Duh, we have to loop. Release the lock to avoid deadlocks */
+		smp_mb__before_clear_bit();	/* need barrier before releasing lock... */
 		clear_bit(0,&global_irq_lock);
 
 		for (;;) {
@@ -305,7 +306,7 @@
 				continue;
 			if (global_irq_lock)
 				continue;
-			if (!local_bh_count() && spin_is_locked(&global_bh_lock))
+			if (!really_local_bh_count() && spin_is_locked(&global_bh_lock))
 				continue;
 			if (!test_and_set_bit(0,&global_irq_lock))
 				break;
@@ -378,14 +379,14 @@
 	__save_flags(flags);
 	if (flags & IA64_PSR_I) {
 		__cli();
-		if (!local_irq_count())
+		if (!really_local_irq_count())
 			get_irqlock();
 	}
 #else
 	__save_flags(flags);
 	if (flags & (1 << EFLAGS_IF_SHIFT)) {
 		__cli();
-		if (!local_irq_count())
+		if (!really_local_irq_count())
 			get_irqlock();
 	}
 #endif
@@ -393,7 +394,7 @@
 
 void __global_sti(void)
 {
-	if (!local_irq_count())
+	if (!really_local_irq_count())
 		release_irqlock(smp_processor_id());
 	__sti();
 }
@@ -422,7 +423,7 @@
 	retval = 2 + local_enabled;
 
 	/* check for global flags if we're not in an interrupt */
-	if (!local_irq_count()) {
+	if (!really_local_irq_count()) {
 		if (local_enabled)
 			retval = 1;
 		if (global_irq_holder == cpu)
@@ -529,7 +530,7 @@
 	disable_irq_nosync(irq);
 
 #ifdef CONFIG_SMP
-	if (!local_irq_count()) {
+	if (!really_local_irq_count()) {
 		do {
 			barrier();
 		} while (irq_desc(irq)->status & IRQ_INPROGRESS);
@@ -1009,6 +1010,11 @@
 		rand_initialize_irq(irq);
 	}
 
+	if (new->flags & SA_PERCPU_IRQ) {
+		desc->status |= IRQ_PER_CPU;
+		desc->handler = &irq_type_ia64_lsapic;
+	}
+
 	/*
 	 * The following block of code has to be executed atomically
 	 */
@@ -1089,13 +1095,25 @@
 static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
 
 static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL };
+static char irq_redir [NR_IRQS]; // = { [0 ... NR_IRQS-1] = 1 };
+
+void set_irq_affinity_info(int irq, int hwid, int redir)
+{
+	unsigned long mask = 1UL<<cpu_logical_id(hwid);
+
+	if (irq >= 0 && irq < NR_IRQS) {
+		irq_affinity[irq] = mask;
+		irq_redir[irq] = (char) (redir & 0xff);
+	}
+}
 
 static int irq_affinity_read_proc (char *page, char **start, off_t off,
 			int count, int *eof, void *data)
 {
-	if (count < HEX_DIGITS+1)
+	if (count < HEX_DIGITS+3)
 		return -EINVAL;
-	return sprintf (page, "%08lx\n", irq_affinity[(long)data]);
+	return sprintf (page, "%s%08lx\n", irq_redir[(long)data] ? "r " : "",
+			irq_affinity[(long)data]);
 }
 
 static int irq_affinity_write_proc (struct file *file, const char *buffer,
@@ -1103,11 +1121,20 @@
 {
 	int irq = (long) data, full_count = count, err;
 	unsigned long new_value;
+	const char *buf = buffer;
+	int redir;
 
 	if (!irq_desc(irq)->handler->set_affinity)
 		return -EIO;
 
-	err = parse_hex_value(buffer, count, &new_value);
+	if (buf[0] == 'r' || buf[0] == 'R') {
+		++buf;
+		while (*buf == ' ') ++buf;
+		redir = 1;
+	} else
+		redir = 0;
+
+	err = parse_hex_value(buf, count, &new_value);
 
 	/*
 	 * Do not allow disabling IRQs completely - it's a too easy
@@ -1117,8 +1144,7 @@
 	if (!(new_value & cpu_online_map))
 		return -EINVAL;
 
-	irq_affinity[irq] = new_value;
-	irq_desc(irq)->handler->set_affinity(irq, new_value);
+	irq_desc(irq)->handler->set_affinity(irq | (redir?(1<<31):0), new_value);
 
 	return full_count;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/kernel/ivt.S linux/arch/ia64/kernel/ivt.S
--- linux.orig/arch/ia64/kernel/ivt.S	Fri Nov  9 22:26:17 2001
+++ linux/arch/ia64/kernel/ivt.S	Tue May 28 22:39:18 2002
@@ -275,6 +275,7 @@
 	mov r16=cr.ifa		// get address that caused the TLB miss
 	movl r17=PAGE_KERNEL
 	mov r21=cr.ipsr
+	movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
 	mov r31=pr
 	;;
 #ifdef CONFIG_DISABLE_VHPT
@@ -289,12 +290,12 @@
 (p8)	br.cond.dptk itlb_fault
 #endif
 	extr.u r23=r21,IA64_PSR_CPL0_BIT,2	// extract psr.cpl
+	and r19=r19,r16		// clear ed, reserved bits, and PTE control bits
 	shr.u r18=r16,57	// move address bit 61 to bit 4
-	dep r19=0,r16,IA64_MAX_PHYS_BITS,(64-IA64_MAX_PHYS_BITS)	// clear ed & reserved bits
 	;;
 	andcm r18=0x10,r18	// bit 4=~address-bit(61)
 	cmp.ne p8,p0=r0,r23	// psr.cpl != 0?
-	dep r19=r17,r19,0,12	// insert PTE control bits into r19
+	or r19=r17,r19		// insert PTE control bits into r19
 	;;
 	or r19=r19,r18		// set bit 4 (uncached) if the access was to region 6
 (p8)	br.cond.spnt page_fault
@@ -312,6 +313,7 @@
 	mov r16=cr.ifa		// get address that caused the TLB miss
 	movl r17=PAGE_KERNEL
 	mov r20=cr.isr
+	movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
 	mov r21=cr.ipsr
 	mov r31=pr
 	;;
@@ -328,15 +330,15 @@
 #endif
 	extr.u r23=r21,IA64_PSR_CPL0_BIT,2	// extract psr.cpl
 	tbit.nz p6,p7=r20,IA64_ISR_SP_BIT	// is speculation bit on?
+	and r19=r19,r16		// clear ed, reserved bits, and PTE control bits
 	shr.u r18=r16,57	// move address bit 61 to bit 4
-	dep r19=0,r16,IA64_MAX_PHYS_BITS,(64-IA64_MAX_PHYS_BITS) // clear ed & reserved bits
 	;;
 	andcm r18=0x10,r18	// bit 4=~address-bit(61)
 	cmp.ne p8,p0=r0,r23
 (p8)	br.cond.spnt page_fault
 
 	dep r21=-1,r21,IA64_PSR_ED_BIT,1
-	dep r19=r17,r19,0,12	// insert PTE control bits into r19
+	or r19=r19,r17		// insert PTE control bits into r19
 	;;
 	or r19=r19,r18		// set bit 4 (uncached) if the access was to region 6
 (p6)	mov cr.ipsr=r21
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/kernel/mca.c linux/arch/ia64/kernel/mca.c
--- linux.orig/arch/ia64/kernel/mca.c	Fri Nov  9 22:26:17 2001
+++ linux/arch/ia64/kernel/mca.c	Tue May 28 22:39:27 2002
@@ -3,6 +3,9 @@
  * Purpose:	Generic MCA handling layer
  *
  * Updated for latest kernel
+ * Copyright (C) 2002 Intel
+ * Copyright (C) Jenna Hall (jenna.s.hall@intel.com)
+ *
  * Copyright (C) 2001 Intel
  * Copyright (C) Fred Lewis (frederick.v.lewis@intel.com)
  *
@@ -12,6 +15,11 @@
  * Copyright (C) 1999 Silicon Graphics, Inc.
  * Copyright (C) Vijay Chander(vijay@engr.sgi.com)
  *
+ * 02/01/04 J. Hall	Aligned MCA stack to 16 bytes, added platform vs. CPU
+ *			error flag, set SAL default return values, changed
+ *			error record structure to linked list, added init call
+ *			to sal_get_state_info_size().
+ *
  * 01/01/03 F. Lewis    Added setup of CMCI and CPEI IRQs, logging of corrected
  *                      platform errors, completed code for logging of
  *                      corrected & uncorrected machine check errors, and
@@ -27,6 +35,7 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/smp_lock.h>
+#include <linux/bootmem.h>
 
 #include <asm/machvec.h>
 #include <asm/page.h>
@@ -50,18 +59,22 @@
 ia64_mca_sal_to_os_state_t	ia64_sal_to_os_handoff_state;
 ia64_mca_os_to_sal_state_t	ia64_os_to_sal_handoff_state;
 u64				ia64_mca_proc_state_dump[512];
-u64				ia64_mca_stack[1024];
+u64				ia64_mca_stack[1024] __attribute__((aligned(16)));
 u64				ia64_mca_stackframe[32];
 u64				ia64_mca_bspstore[1024];
 u64				ia64_init_stack[INIT_TASK_SIZE] __attribute__((aligned(16)));
+u64				ia64_mca_sal_data_area[1356];
+u64				ia64_mca_min_state_save_info;
+u64				ia64_tlb_functional;
+u64				ia64_os_mca_recovery_successful;
 
 static void			ia64_mca_wakeup_ipi_wait(void);
 static void			ia64_mca_wakeup(int cpu);
 static void			ia64_mca_wakeup_all(void);
 static void			ia64_log_init(int);
-extern void		        ia64_monarch_init_handler (void);
-extern void		        ia64_slave_init_handler (void);
-extern struct hw_interrupt_type irq_type_iosapic_level;
+extern void			ia64_monarch_init_handler (void);
+extern void			ia64_slave_init_handler (void);
+extern struct hw_interrupt_type	irq_type_iosapic_level;
 
 static struct irqaction cmci_irqaction = {
 	handler:    ia64_mca_cmc_int_handler,
@@ -95,25 +108,31 @@
  *  memory.
  *
  *  Inputs  :   sal_info_type   (Type of error record MCA/CMC/CPE/INIT)
- *  Outputs :   None
+ *  Outputs :   platform error status
  */
-void
+int
 ia64_mca_log_sal_error_record(int sal_info_type)
 {
+	int platform_err = 0;
+
 	/* Get the MCA error record */
 	if (!ia64_log_get(sal_info_type, (prfunc_t)printk))
-		return;                 // no record retrieved
+		return platform_err;                 // no record retrieved
 
-	/* Log the error record */
-	ia64_log_print(sal_info_type, (prfunc_t)printk);
+	/* TODO:
+	 * 1. analyze error logs to determine recoverability
+	 * 2. perform error recovery procedures, if applicable
+	 * 3. set ia64_os_mca_recovery_successful flag, if applicable
+	 */
 
-	/* Clear the CMC SAL logs now that they have been logged */
+	platform_err = ia64_log_print(sal_info_type, (prfunc_t)printk);
 	ia64_sal_clear_state_info(sal_info_type);
+
+	return platform_err;
 }
 
 /*
- * hack for now, add platform dependent handlers
- * here
+ * platform dependent error handling
  */
 #ifndef PLATFORM_MCA_HANDLERS
 void
@@ -275,8 +294,8 @@
 	cmcv_reg_t	cmcv;
 
 	cmcv.cmcv_regval	= 0;
-	cmcv.cmcv_mask      = 0;        /* Unmask/enable interrupt */
-	cmcv.cmcv_vector    = IA64_CMC_VECTOR;
+	cmcv.cmcv_mask		= 0;        /* Unmask/enable interrupt */
+	cmcv.cmcv_vector	= IA64_CMC_VECTOR;
 	ia64_set_cmcv(cmcv.cmcv_regval);
 
 	IA64_MCA_DEBUG("ia64_mca_platform_init: CPU %d corrected "
@@ -374,6 +393,9 @@
 
 	IA64_MCA_DEBUG("ia64_mca_init: begin\n");
 
+	/* initialize recovery success indicator */
+	ia64_os_mca_recovery_successful = 0;
+
 	/* Clear the Rendez checkin flag for all cpus */
 	for(i = 0 ; i < NR_CPUS; i++)
 		ia64_mc_info.imi_rendez_checkin[i] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE;
@@ -459,7 +481,7 @@
 
 	/*
 	 *  Configure the CMCI vector and handler. Interrupts for CMC are
-	 *  per-processor, so AP CMC interrupts are setup in smp_callin() (smp.c).
+	 *  per-processor, so AP CMC interrupts are setup in smp_callin() (smpboot.c).
 	 */
 	register_percpu_irq(IA64_CMC_VECTOR, &cmci_irqaction);
 	ia64_mca_cmc_vector_setup();       /* Setup vector on BSP & enable */
@@ -498,6 +520,9 @@
 	ia64_log_init(SAL_INFO_TYPE_CMC);
 	ia64_log_init(SAL_INFO_TYPE_CPE);
 
+	/* Zero the min state save info */
+	ia64_mca_min_state_save_info = 0;
+
 #if defined(MCA_TEST)
 	mca_test();
 #endif /* #if defined(MCA_TEST) */
@@ -576,7 +601,7 @@
 	int cpu;
 
 	/* Clear the Rendez checkin flag for all cpus */
-	for(cpu = 0 ; cpu < smp_num_cpus; cpu++)
+	for(cpu = 0; cpu < smp_num_cpus; cpu++)
 		if (ia64_mc_info.imi_rendez_checkin[cpu] == IA64_MCA_RENDEZ_CHECKIN_DONE)
 			ia64_mca_wakeup(cpu);
 
@@ -668,6 +693,13 @@
 
 	/* Cold Boot for uncorrectable MCA */
 	ia64_os_to_sal_handoff_state.imots_os_status = IA64_MCA_COLD_BOOT;
+
+	/* Default = tell SAL to return to same context */
+	ia64_os_to_sal_handoff_state.imots_context = IA64_MCA_SAME_CONTEXT;
+
+	/* Register pointer to new min state values */
+	/* NOTE: need to do something with this during recovery phase */
+	ia64_os_to_sal_handoff_state.imots_new_min_state = &ia64_mca_min_state_save_info;
 }
 
 /*
@@ -678,10 +710,10 @@
  *	This is the place where the core of OS MCA handling is done.
  *	Right now the logs are extracted and displayed in a well-defined
  *	format. This handler code is supposed to be run only on the
- *	monarch processor. Once the  monarch is done with MCA handling
+ *	monarch processor. Once the monarch is done with MCA handling
  *	further MCA logging is enabled by clearing logs.
  *	Monarch also has the duty of sending wakeup-IPIs to pull the
- *  slave processors out of rendezvous spinloop.
+ *	slave processors out of rendezvous spinloop.
  *
  *  Inputs  :   None
  *  Outputs :   None
@@ -689,20 +721,16 @@
 void
 ia64_mca_ucmc_handler(void)
 {
-#if 0   /* stubbed out @FVL */
-	/*
-	 *  Attempting to log a DBE error Causes "reserved register/field panic"
-	 *  in printk.
-	 */
+	int platform_err = 0;
 
 	/* Get the MCA error record and log it */
-	ia64_mca_log_sal_error_record(SAL_INFO_TYPE_MCA);
-#endif  /* stubbed out @FVL */
+	platform_err = ia64_mca_log_sal_error_record(SAL_INFO_TYPE_MCA);
 
 	/*
 	 *  Do Platform-specific mca error handling if required.
 	 */
-	mca_handler_platform() ;
+	if (platform_err)
+		mca_handler_platform();
 
 	/*
 	 *  Wakeup all the processors which are spinning in the rendezvous
@@ -749,13 +777,16 @@
 {
 	spinlock_t	isl_lock;
 	int		isl_index;
-	ia64_err_rec_t  isl_log[IA64_MAX_LOGS]; /* need space to store header + error log */
+	ia64_err_rec_t  *isl_log[IA64_MAX_LOGS]; /* need space to store header + error log */
 } ia64_state_log_t;
 
 static ia64_state_log_t ia64_state_log[IA64_MAX_LOG_TYPES];
 
-/* Note:  Some of these macros assume IA64_MAX_LOGS is always 2.  Should be */
-/* fixed. @FVL                                                              */
+#define IA64_LOG_ALLOCATE(it, size) \
+	{ia64_state_log[it].isl_log[IA64_LOG_CURR_INDEX(it)] = \
+		(ia64_err_rec_t *)alloc_bootmem(size); \
+	ia64_state_log[it].isl_log[IA64_LOG_NEXT_INDEX(it)] = \
+		(ia64_err_rec_t *)alloc_bootmem(size);}
 #define IA64_LOG_LOCK_INIT(it) spin_lock_init(&ia64_state_log[it].isl_lock)
 #define IA64_LOG_LOCK(it)      spin_lock_irqsave(&ia64_state_log[it].isl_lock, s)
 #define IA64_LOG_UNLOCK(it)    spin_unlock_irqrestore(&ia64_state_log[it].isl_lock,s)
@@ -765,13 +796,13 @@
     ia64_state_log[it].isl_index = 1 - ia64_state_log[it].isl_index
 #define IA64_LOG_INDEX_DEC(it) \
     ia64_state_log[it].isl_index = 1 - ia64_state_log[it].isl_index
-#define IA64_LOG_NEXT_BUFFER(it)   (void *)(&(ia64_state_log[it].isl_log[IA64_LOG_NEXT_INDEX(it)]))
-#define IA64_LOG_CURR_BUFFER(it)   (void *)(&(ia64_state_log[it].isl_log[IA64_LOG_CURR_INDEX(it)]))
+#define IA64_LOG_NEXT_BUFFER(it)   (void *)((ia64_state_log[it].isl_log[IA64_LOG_NEXT_INDEX(it)]))
+#define IA64_LOG_CURR_BUFFER(it)   (void *)((ia64_state_log[it].isl_log[IA64_LOG_CURR_INDEX(it)]))
 
 /*
  * C portion of the OS INIT handler
  *
- * Called from ia64_<monarch/slave>_init_handler
+ * Called from ia64_monarch_init_handler
  *
  * Inputs: pointer to pt_regs where processor info was saved.
  *
@@ -885,10 +916,18 @@
 void
 ia64_log_init(int sal_info_type)
 {
-	IA64_LOG_LOCK_INIT(sal_info_type);
+	u64	max_size = 0;
+
 	IA64_LOG_NEXT_INDEX(sal_info_type) = 0;
-	memset(IA64_LOG_NEXT_BUFFER(sal_info_type), 0,
-	       sizeof(ia64_err_rec_t) * IA64_MAX_LOGS);
+	IA64_LOG_LOCK_INIT(sal_info_type);
+
+	// SAL will tell us the maximum size of any error record of this type
+	max_size = ia64_sal_get_state_info_size(sal_info_type);
+
+	// set up OS data structures to hold error info
+	IA64_LOG_ALLOCATE(sal_info_type, max_size);
+	memset(IA64_LOG_CURR_BUFFER(sal_info_type), 0, max_size);
+	memset(IA64_LOG_NEXT_BUFFER(sal_info_type), 0, max_size);
 }
 
 /*
@@ -923,8 +962,7 @@
 		return total_len;
 	} else {
 		IA64_LOG_UNLOCK(sal_info_type);
-		prfunc("ia64_log_get: Failed to retrieve SAL error record type %d\n",
-		       sal_info_type);
+		prfunc("ia64_log_get: No SAL error record available for type %d\n", sal_info_type);
 		return 0;
 	}
 }
@@ -1268,7 +1306,7 @@
 	}
 
 	if (mdei->valid.oem_data) {
-		ia64_log_prt_oem_data((int)mdei->header.len,
+		platform_mem_dev_err_print((int)mdei->header.len,
 				      (int)sizeof(sal_log_mem_dev_err_info_t) - 1,
 				      &(mdei->oem_data[0]), prfunc);
 	}
@@ -1357,7 +1395,7 @@
 		prfunc("\n");
 
 	if (pbei->valid.oem_data) {
-		ia64_log_prt_oem_data((int)pbei->header.len,
+		platform_pci_bus_err_print((int)pbei->header.len,
 				      (int)sizeof(sal_log_pci_bus_err_info_t) - 1,
 				      &(pbei->oem_data[0]), prfunc);
 	}
@@ -1456,7 +1494,7 @@
 		}
 	}
 	if (pcei->valid.oem_data) {
-		ia64_log_prt_oem_data((int)pcei->header.len, n_pci_data,
+		platform_pci_comp_err_print((int)pcei->header.len, n_pci_data,
 				      p_oem_data, prfunc);
 		prfunc("\n");
 	}
@@ -1485,7 +1523,7 @@
 		ia64_log_prt_guid(&psei->guid, prfunc);
 	}
 	if (psei->valid.oem_data) {
-		ia64_log_prt_oem_data((int)psei->header.len,
+		platform_plat_specific_err_print((int)psei->header.len,
 				      (int)sizeof(sal_log_plat_specific_err_info_t) - 1,
 				      &(psei->oem_data[0]), prfunc);
 	}
@@ -1519,7 +1557,7 @@
 	if (hcei->valid.bus_spec_data)
 		prfunc(" Bus Specific Data: %#lx", hcei->bus_spec_data);
 	if (hcei->valid.oem_data) {
-		ia64_log_prt_oem_data((int)hcei->header.len,
+		platform_host_ctlr_err_print((int)hcei->header.len,
 				      (int)sizeof(sal_log_host_ctlr_err_info_t) - 1,
 				      &(hcei->oem_data[0]), prfunc);
 	}
@@ -1553,7 +1591,7 @@
 	if (pbei->valid.bus_spec_data)
 		prfunc(" Bus Specific Data: %#lx", pbei->bus_spec_data);
 	if (pbei->valid.oem_data) {
-		ia64_log_prt_oem_data((int)pbei->header.len,
+		platform_plat_bus_err_print((int)pbei->header.len,
 				      (int)sizeof(sal_log_plat_bus_err_info_t) - 1,
 				      &(pbei->oem_data[0]), prfunc);
 	}
@@ -1745,17 +1783,18 @@
  *  Inputs  :   lh      (Pointer to the sal error record header with format
  *                       specified by the SAL spec).
  *              prfunc  (fn ptr of log output function to use)
- *  Outputs :   None
+ *  Outputs :	platform error status
  */
-void
+int
 ia64_log_platform_info_print (sal_log_record_header_t *lh, prfunc_t prfunc)
 {
-	sal_log_section_hdr_t       *slsh;
-	int                         n_sects;
-	int                         ercd_pos;
+	sal_log_section_hdr_t	*slsh;
+	int			n_sects;
+	int			ercd_pos;
+	int			platform_err = 0;
 
 	if (!lh)
-		return;
+		return platform_err;
 
 #ifdef MCA_PRT_XTRA_DATA    // for test only @FVL
 	ia64_log_prt_record_header(lh, prfunc);
@@ -1765,7 +1804,7 @@
 		IA64_MCA_DEBUG("ia64_mca_log_print: "
 			       "truncated SAL error record. len = %d\n",
 			       lh->len);
-		return;
+		return platform_err;
 	}
 
 	/* Print record header info */
@@ -1796,35 +1835,43 @@
 			ia64_log_proc_dev_err_info_print((sal_log_processor_info_t *)slsh,
 							 prfunc);
 		} else if (efi_guidcmp(slsh->guid, SAL_PLAT_MEM_DEV_ERR_SECT_GUID) == 0) {
+			platform_err = 1;
 			prfunc("+Platform Memory Device Error Info Section\n");
 			ia64_log_mem_dev_err_info_print((sal_log_mem_dev_err_info_t *)slsh,
 							prfunc);
 		} else if (efi_guidcmp(slsh->guid, SAL_PLAT_SEL_DEV_ERR_SECT_GUID) == 0) {
+			platform_err = 1;
 			prfunc("+Platform SEL Device Error Info Section\n");
 			ia64_log_sel_dev_err_info_print((sal_log_sel_dev_err_info_t *)slsh,
 							prfunc);
 		} else if (efi_guidcmp(slsh->guid, SAL_PLAT_PCI_BUS_ERR_SECT_GUID) == 0) {
+			platform_err = 1;
 			prfunc("+Platform PCI Bus Error Info Section\n");
 			ia64_log_pci_bus_err_info_print((sal_log_pci_bus_err_info_t *)slsh,
 							prfunc);
 		} else if (efi_guidcmp(slsh->guid, SAL_PLAT_SMBIOS_DEV_ERR_SECT_GUID) == 0) {
+			platform_err = 1;
 			prfunc("+Platform SMBIOS Device Error Info Section\n");
 			ia64_log_smbios_dev_err_info_print((sal_log_smbios_dev_err_info_t *)slsh,
 							   prfunc);
 		} else if (efi_guidcmp(slsh->guid, SAL_PLAT_PCI_COMP_ERR_SECT_GUID) == 0) {
+			platform_err = 1;
 			prfunc("+Platform PCI Component Error Info Section\n");
 			ia64_log_pci_comp_err_info_print((sal_log_pci_comp_err_info_t *)slsh,
 							 prfunc);
 		} else if (efi_guidcmp(slsh->guid, SAL_PLAT_SPECIFIC_ERR_SECT_GUID) == 0) {
+			platform_err = 1;
 			prfunc("+Platform Specific Error Info Section\n");
 			ia64_log_plat_specific_err_info_print((sal_log_plat_specific_err_info_t *)
 							      slsh,
 							      prfunc);
 		} else if (efi_guidcmp(slsh->guid, SAL_PLAT_HOST_CTLR_ERR_SECT_GUID) == 0) {
+			platform_err = 1;
 			prfunc("+Platform Host Controller Error Info Section\n");
 			ia64_log_host_ctlr_err_info_print((sal_log_host_ctlr_err_info_t *)slsh,
 							  prfunc);
 		} else if (efi_guidcmp(slsh->guid, SAL_PLAT_BUS_ERR_SECT_GUID) == 0) {
+			platform_err = 1;
 			prfunc("+Platform Bus Error Info Section\n");
 			ia64_log_plat_bus_err_info_print((sal_log_plat_bus_err_info_t *)slsh,
 							 prfunc);
@@ -1838,8 +1885,9 @@
 		       n_sects, lh->len);
 	if (!n_sects) {
 		prfunc("No Platform Error Info Sections found\n");
-		return;
+		return platform_err;
 	}
+	return platform_err;
 }
 
 /*
@@ -1849,15 +1897,17 @@
  *
  *  Inputs   :  info_type   (SAL_INFO_TYPE_{MCA,INIT,CMC,CPE})
  *              prfunc      (fn ptr of log output function to use)
- * Outputs	:	None
+ * Outputs	:	platform error status
  */
-void
+int
 ia64_log_print(int sal_info_type, prfunc_t prfunc)
 {
+	int platform_err = 0;
+
 	switch(sal_info_type) {
 	      case SAL_INFO_TYPE_MCA:
 		prfunc("+BEGIN HARDWARE ERROR STATE AT MCA\n");
-		ia64_log_platform_info_print(IA64_LOG_CURR_BUFFER(sal_info_type), prfunc);
+		platform_err = ia64_log_platform_info_print(IA64_LOG_CURR_BUFFER(sal_info_type), prfunc);
 		prfunc("+END HARDWARE ERROR STATE AT MCA\n");
 		break;
 	      case SAL_INFO_TYPE_INIT:
@@ -1877,4 +1927,5 @@
 		prfunc("+MCA UNKNOWN ERROR LOG (UNIMPLEMENTED)\n");
 		break;
 	}
+	return platform_err;
 }
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/kernel/mca_asm.S linux/arch/ia64/kernel/mca_asm.S
--- linux.orig/arch/ia64/kernel/mca_asm.S	Fri Nov  9 22:26:17 2001
+++ linux/arch/ia64/kernel/mca_asm.S	Tue May 28 22:39:22 2002
@@ -7,6 +7,12 @@
 // 00/03/29 cfleck Added code to save INIT handoff state in pt_regs format, switch to temp
 //		   kstack, switch modes, jump to C INIT handler
 //
+// 02/01/04 J.Hall <jenna.s.hall@intel.com>
+//		   Before entering virtual mode code:
+//		   1. Check for TLB CPU error
+//		   2. Restore current thread pointer to kr6
+//		   3. Move stack ptr 16 bytes to conform to C calling convention
+//
 #include <linux/config.h>
 
 #include <asm/asmmacro.h>
@@ -21,10 +27,21 @@
  */
 #define	MINSTATE_PHYS	/* Make sure stack access is physical for MINSTATE */
 
+/*
+ * Needed for ia64_sal call
+ */
+#define SAL_GET_STATE_INFO      0x01000001
+
+/*
+ * Needed for return context to SAL
+ */
+#define IA64_MCA_SAME_CONTEXT	0x0
+#define IA64_MCA_COLD_BOOT	-2
+
 #include "minstate.h"
 
 /*
- *  SAL_TO_OS_MCA_HANDOFF_STATE (SAL 3.0 spec)
+ * SAL_TO_OS_MCA_HANDOFF_STATE (SAL 3.0 spec)
  *		1. GR1 = OS GP
  *		2. GR8 = PAL_PROC physical address
  *		3. GR9 = SAL_PROC physical address
@@ -40,26 +57,34 @@
 	st8	[_tmp]=r9,0x08;;			\
 	st8	[_tmp]=r10,0x08;;			\
 	st8	[_tmp]=r11,0x08;;			\
-	st8	[_tmp]=r12,0x08;;
+	st8	[_tmp]=r12,0x08
 
 /*
- *  OS_MCA_TO_SAL_HANDOFF_STATE (SAL 3.0 spec)
- *      1. GR8 = OS_MCA return status
+ * OS_MCA_TO_SAL_HANDOFF_STATE (SAL 3.0 spec)
+ * (p6) is executed if we never entered virtual mode (TLB error)
+ * (p7) is executed if we entered virtual mode as expected (normal case)
+ *	1. GR8 = OS_MCA return status
  *	2. GR9 = SAL GP (physical)
- *      3. GR10 = 0/1 returning same/new context
- *      4. GR22 = New min state save area pointer
- *      returns ptr to SAL rtn save loc in _tmp
+ *	3. GR10 = 0/1 returning same/new context
+ *	4. GR22 = New min state save area pointer
+ *	returns ptr to SAL rtn save loc in _tmp
  */
-#define OS_MCA_TO_SAL_HANDOFF_STATE_RESTORE(_tmp)				\
-	movl	_tmp=ia64_os_to_sal_handoff_state;;				\
-	DATA_VA_TO_PA(_tmp);;							\
-	ld8	r8=[_tmp],0x08;;						\
-	ld8	r9=[_tmp],0x08;;						\
-	ld8     r10=[_tmp],0x08;;						\
-	ld8     r22=[_tmp],0x08;;						\
-	movl    _tmp=ia64_sal_to_os_handoff_state;;				\
-	DATA_VA_TO_PA(_tmp);;							\
-	add     _tmp=0x28,_tmp;;            // point to SAL rtn save location
+#define OS_MCA_TO_SAL_HANDOFF_STATE_RESTORE(_tmp)	\
+(p6)	movl	_tmp=ia64_sal_to_os_handoff_state;;	\
+(p7)	movl	_tmp=ia64_os_to_sal_handoff_state;;	\
+	DATA_VA_TO_PA(_tmp);;				\
+(p6)	movl	r8=IA64_MCA_COLD_BOOT;			\
+(p6)	movl	r10=IA64_MCA_SAME_CONTEXT;		\
+(p6)	add     _tmp=0x18,_tmp;;			\
+(p6)	ld8	r9=[_tmp],0x10;				\
+(p6)	movl	r22=ia64_mca_min_state_save_info;;	\
+(p7)	ld8	r8=[_tmp],0x08;;			\
+(p7)	ld8	r9=[_tmp],0x08;;			\
+(p7)	ld8     r10=[_tmp],0x08;;			\
+(p7)	ld8     r22=[_tmp],0x08;;			\
+	DATA_VA_TO_PA(r22)
+	// now _tmp is pointing to SAL rtn save location
+
 
 	.global ia64_os_mca_dispatch
 	.global ia64_os_mca_dispatch_end
@@ -70,6 +95,9 @@
 	.global	ia64_mca_stackframe
 	.global	ia64_mca_bspstore
 	.global ia64_init_stack
+	.global ia64_mca_sal_data_area
+	.global ia64_tlb_functional
+	.global ia64_mca_min_state_save_info
 
 	.text
 	.align 16
@@ -90,26 +118,34 @@
 	//	  for ia64_mca_sal_to_os_state_t has been
 	//	  defined in include/asm/mca.h
 	SAL_TO_OS_MCA_HANDOFF_STATE_SAVE(r2)
+	;;
 
 	// LOG PROCESSOR STATE INFO FROM HERE ON..
-	;;
 begin_os_mca_dump:
 	br	ia64_os_mca_proc_state_dump;;
 
 ia64_os_mca_done_dump:
 
 	// Setup new stack frame for OS_MCA handling
-	movl    r2=ia64_mca_bspstore;;      // local bspstore area location in r2
+	movl	r2=ia64_mca_bspstore;;	// local bspstore area location in r2
 	DATA_VA_TO_PA(r2);;
-	movl    r3=ia64_mca_stackframe;;    // save stack frame to memory in r3
+	movl	r3=ia64_mca_stackframe;; // save stack frame to memory in r3
 	DATA_VA_TO_PA(r3);;
-	rse_switch_context(r6,r3,r2);;                  // RSC management in this new context
-	movl        r12=ia64_mca_stack;;
-	mov     r2=8*1024;;                 // stack size must be same as c array
-	add     r12=r2,r12;;                // stack base @ bottom of array
+	rse_switch_context(r6,r3,r2);;	// RSC management in this new context
+	movl	r12=ia64_mca_stack
+	mov	r2=8*1024;;		// stack size must be same as C array
+	add	r12=r2,r12;;		// stack base @ bottom of array
+	adds	r12=-16,r12;;		// allow 16 bytes of scratch
+					// (C calling convention)
 	DATA_VA_TO_PA(r12);;
 
-	// Enter virtual mode from physical mode
+	// Check to see if the MCA resulted from a TLB error
+begin_tlb_error_check:
+        br      ia64_os_mca_tlb_error_check;;
+
+done_tlb_error_check:
+
+        // If TLB is functional, enter virtual mode from physical mode
 	VIRTUAL_MODE_ENTER(r2, r3, ia64_os_mca_virtual_begin, r4)
 ia64_os_mca_virtual_begin:
 
@@ -130,25 +166,28 @@
 #endif	/* #if defined(MCA_TEST) */
 
 	// restore the original stack frame here
-	movl    r2=ia64_mca_stackframe               // restore stack frame from memory at r2
+	movl    r2=ia64_mca_stackframe	// restore stack frame from memory at r2
 	;;
 	DATA_VA_TO_PA(r2)
 	movl    r4=IA64_PSR_MC
 	;;
-	rse_return_context(r4,r3,r2)                 // switch from interrupt context for RSE
+	rse_return_context(r4,r3,r2)	// switch from interrupt context for RSE
 
 	// let us restore all the registers from our PSI structure
-	mov		r8=gp
+	mov	r8=gp
 	;;
 begin_os_mca_restore:
 	br	ia64_os_mca_proc_state_restore;;
 
 ia64_os_mca_done_restore:
-	;;
+	movl	r3=ia64_tlb_functional;;
+	DATA_VA_TO_PA(r3);;
+	ld8	r3=[r3];;
+	cmp.eq	p6,p7=r0,r3;;
+	OS_MCA_TO_SAL_HANDOFF_STATE_RESTORE(r2);;
 	// branch back to SALE_CHECK
-	OS_MCA_TO_SAL_HANDOFF_STATE_RESTORE(r2)
 	ld8		r3=[r2];;
-	mov		b0=r3;;			      // SAL_CHECK return address
+	mov		b0=r3;;		// SAL_CHECK return address
 	br		b0
 	;;
 ia64_os_mca_dispatch_end:
@@ -405,7 +444,7 @@
 	movl		r2=ia64_mca_proc_state_dump	// Convert virtual address
 	;;						// of OS state dump area
 	DATA_VA_TO_PA(r2)				// to physical address
-	;;
+
 restore_GRs:                                    // restore bank-1 GRs 16-31
 	bsw.1;;
 	add		r3=16*8,r2;;                // to get to NaT of GR 16-31
@@ -621,6 +660,80 @@
 
 //EndStub//////////////////////////////////////////////////////////////////////
 
+//++
+// Name:
+//	ia64_os_mca_tlb_error_check()
+//
+// Stub Description:
+//
+//	This stub checks to see if the MCA resulted from a TLB error
+//
+//--
+
+ia64_os_mca_tlb_error_check:
+
+	// Retrieve sal data structure for uncorrected MCA
+
+	// Make the ia64_sal_get_state_info() call
+	movl	r4=ia64_mca_sal_data_area;;
+	movl	r7=ia64_sal;;
+	mov	r6=r1			// save gp
+	DATA_VA_TO_PA(r4)		// convert to physical address
+	DATA_VA_TO_PA(r7);;		// convert to physical address
+	ld8	r7=[r7]			// get addr of pdesc from ia64_sal
+	movl	r3=SAL_GET_STATE_INFO;;
+	DATA_VA_TO_PA(r7);;		// convert to physical address
+	ld8	r8=[r7],8;;		// get pdesc function pointer
+	DATA_VA_TO_PA(r8)		// convert to physical address
+	ld8	r1=[r7];;		// set new (ia64_sal) gp
+	DATA_VA_TO_PA(r1)		// convert to physical address
+	mov	b6=r8
+
+	alloc	r5=ar.pfs,8,0,8,0;;	// allocate stack frame for SAL call
+	mov	out0=r3			// which SAL proc to call
+	mov	out1=r0			// error type == MCA
+	mov	out2=r0			// null arg
+	mov	out3=r4			// data copy area
+	mov	out4=r0			// null arg
+	mov	out5=r0			// null arg
+	mov	out6=r0			// null arg
+	mov	out7=r0;;		// null arg
+
+	br.call.sptk.few	b0=b6;;
+
+	mov	r1=r6			// restore gp
+	mov	ar.pfs=r5;;		// restore ar.pfs
+
+	movl	r6=ia64_tlb_functional;;
+	DATA_VA_TO_PA(r6)		// needed later
+
+	cmp.eq	p6,p7=r0,r8;;		// check SAL call return address
+(p7)	st8	[r6]=r0			// clear tlb_functional flag
+(p7)    br	tlb_failure		// error; return to SAL
+
+	// examine processor error log for type of error
+	add	r4=40+24,r4;;		// parse past record header (length=40)
+					// and section header (length=24)
+	ld4	r4=[r4]			// get valid field of processor log
+	mov	r5=0xf00;;
+	and	r5=r4,r5;;		// read bits 8-11 of valid field
+					// to determine if we have a TLB error
+	movl	r3=0x1
+	cmp.eq	p6,p7=r0,r5;;
+	// if no TLB failure, set tlb_functional flag
+(p6)	st8	[r6]=r3
+	// else clear flag
+(p7)	st8	[r6]=r0
+
+	// if no TLB failure, continue with normal virtual mode logging
+(p6)    br	done_tlb_error_check
+	// else no point in entering virtual mode for logging
+tlb_failure:
+	br      ia64_os_mca_virtual_end
+
+//EndStub//////////////////////////////////////////////////////////////////////
+
+
 // ok, the issue here is that we need to save state information so
 // it can be useable by the kernel debugger and show regs routines.
 // In order to do this, our best bet is save the current state (plus
@@ -633,7 +746,7 @@
 // This has been defined for registration purposes with SAL
 // as a part of ia64_mca_init.
 //
-// When we get here, the follow registers have been
+// When we get here, the following registers have been
 // set by the SAL for our use
 //
 //		1. GR1 = OS INIT GP
@@ -649,42 +762,10 @@
 
 
 GLOBAL_ENTRY(ia64_monarch_init_handler)
-#if defined(CONFIG_SMP) && defined(SAL_MPINIT_WORKAROUND)
-	//
-	// work around SAL bug that sends all processors to monarch entry
-	//
-	mov	r17=cr.lid
-	// XXX fix me: this is wrong: hard_smp_processor_id() is a pair of lid/eid
-	movl	r18=ia64_cpu_to_sapicid
-	;;
-	dep	r18=0,r18,61,3		// convert to physical address
-	;;
-	shr.u	r17=r17,16
-	ld4	r18=[r18]		// get the BSP ID
-	;;
-	dep	r17=0,r17,16,48
-	;;
-	cmp4.ne	p6,p0=r17,r18		// Am I the BSP ?
-(p6)	br.cond.spnt slave_init_spin_me
-	;;
-#endif
-
 
-//
-// ok, the first thing we do is stash the information
-// the SAL passed to os
-//
-_tmp = r2
-	movl	_tmp=ia64_sal_to_os_handoff_state
-	;;
-	dep	_tmp=0,_tmp, 61, 3	// get physical address
+	// stash the information the SAL passed to os
+	SAL_TO_OS_MCA_HANDOFF_STATE_SAVE(r2)
 	;;
-	st8	[_tmp]=r1,0x08;;
-	st8	[_tmp]=r8,0x08;;
-	st8	[_tmp]=r9,0x08;;
-	st8	[_tmp]=r10,0x08;;
-	st8	[_tmp]=r11,0x08;;
-	st8	[_tmp]=r12,0x08;;
 
 // now we want to save information so we can dump registers
 	SAVE_MIN_WITH_COVER
@@ -695,12 +776,10 @@
 	;;
 	SAVE_REST
 
-// ok, enough should be saved at this point to be dangerous, and  supply
+// ok, enough should be saved at this point to be dangerous, and supply
 // information for a dump
 // We need to switch to Virtual mode before hitting the C functions.
-//
-//
-//
+
 	movl	r2=IA64_PSR_IT|IA64_PSR_IC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_DFH|IA64_PSR_BN
 	mov	r3=psr	// get the current psr, minimum enabled at this point
 	;;
@@ -708,8 +787,8 @@
 	;;
 	movl	r3=IVirtual_Switch
 	;;
-	mov	cr.iip=r3		// short return to set the appropriate bits
-	mov	cr.ipsr=r2		// need to do an rfi to set appropriate bits
+	mov	cr.iip=r3	// short return to set the appropriate bits
+	mov	cr.ipsr=r2	// need to do an rfi to set appropriate bits
 	;;
 	rfi
 	;;
@@ -717,7 +796,7 @@
 	//
 	// We should now be running virtual
 	//
-	// Lets call the C handler to get the rest of the state info
+	// Let's call the C handler to get the rest of the state info
 	//
 	alloc r14=ar.pfs,0,0,1,0		// now it's safe (must be first in insn group!)
 	;;					//
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/kernel/palinfo.c linux/arch/ia64/kernel/palinfo.c
--- linux.orig/arch/ia64/kernel/palinfo.c	Fri Nov  9 22:26:17 2001
+++ linux/arch/ia64/kernel/palinfo.c	Tue May 28 22:39:13 2002
@@ -724,7 +724,7 @@
 
 		status = ia64_pal_tr_read(j, i, tr_buffer, &tr_valid);
 		if (status != 0) {
-			printk(__FUNCTION__ " pal call failed on tr[%d:%d]=%ld\n", i, j, status);
+			printk("palinfo: pal call failed on tr[%d:%d]=%ld\n", i, j, status);
 			continue;
 		}
 
@@ -842,9 +842,8 @@
 palinfo_smp_call(void *info)
 {
 	palinfo_smp_data_t *data = (palinfo_smp_data_t *)info;
-	/* printk(__FUNCTION__" called on CPU %d\n", smp_processor_id());*/
 	if (data == NULL) {
-		printk(KERN_ERR __FUNCTION__" data pointer is NULL\n");
+		printk("%s palinfo: data pointer is NULL\n", KERN_ERR);
 		data->ret = 0; /* no output */
 		return;
 	}
@@ -868,11 +867,10 @@
 	ptr.page = page;
 	ptr.ret  = 0; /* just in case */
 
-	/*printk(__FUNCTION__" calling CPU %d from CPU %d for function %d\n", f->req_cpu,smp_processor_id(), f->func_id);*/
 
 	/* will send IPI to other CPU and wait for completion of remote call */
 	if ((ret=smp_call_function_single(f->req_cpu, palinfo_smp_call, &ptr, 0, 1))) {
-		printk(__FUNCTION__" remote CPU call from %d to %d on function %d: error %d\n", smp_processor_id(), f->req_cpu, f->func_id, ret);
+		printk("palinfo: remote CPU call from %d to %d on function %d: error %d\n", smp_processor_id(), f->req_cpu, f->func_id, ret);
 		return 0;
 	}
 	return ptr.ret;
@@ -881,7 +879,7 @@
 static
 int palinfo_handle_smp(pal_func_cpu_u_t *f, char *page)
 {
-	printk(__FUNCTION__" should not be called with non SMP kernel\n");
+	printk("palinfo: should not be called with non SMP kernel\n");
 	return 0;
 }
 #endif /* CONFIG_SMP */
diff -Naur -X /home/marcelo/lib/dontdiff linux.orig/arch/ia64/kernel/perfmon.c linux/arch/ia64/kernel/perfmon.c
--- linux.orig/arch/ia64/kernel/perfmon.c	Fri Nov  9 22:26:17 2001
+++ linux/arch/ia64/kernel/perfmon.c	Tue May 28 22:39:24 2002
@@ -1,13 +1,16 @@
 /*
- * This file contains the code to configure and read/write the ia64 performance
- * monitoring stuff.
+ * This file implements the perfmon subsystem which is used
+ * to program the IA-64 Performance Monitoring Unit (PMU).
  *
  * Originaly Written by Ganesh Venkitachalam, IBM Corp.
- * Modifications by David Mosberger-Tang, Hewlett-Packard Co.
- * Modifications by Stephane Eranian, Hewlett-Packard Co.
  * Copyright (C) 1999 Ganesh Venkitachalam <venkitac@us.ibm.com>
- * Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 2000-2001 Stephane Eranian <eranian@hpl.hp.com>
+ *
+ * Modifications by Stephane Eranian, Hewlett-Packard Co.
+ * Modifications by David Mosberger-Tang, Hewlett-Packard Co.
+ *
+ * Copyright (C) 1999-2002  Hewlett Packard Co
+ *               Stephane Eranian <eranian@hpl.hp.com>
+ *               David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
 #include <linux/config.h>
@@ -22,151 +25,137 @@
 #include <linux/mm.h>
 
 #include <asm/bitops.h>
-#include <asm/efi.h>
 #include <asm/errno.h>
-#include <asm/hw_irq.h>
 #include <asm/page.h>
 #include <asm/pal.h>
 #include <asm/perfmon.h>
-#include <asm/pgtable.h>
 #include <asm/processor.h>
 #include <asm/signal.h>
 #include <asm/system.h>
-#include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/delay.h> /* for ia64_get_itc() */
 
 #ifdef CONFIG_PERFMON
 
-#define PFM_VERSION		"0.3"
-#define PFM_SMPL_HDR_VERSION	1
-
-#define PMU_FIRST_COUNTER	4	/* first generic counter */
-
-#define PFM_WRITE_PMCS		0xa0
-#define PFM_WRITE_PMDS		0xa1
-#define PFM_READ_PMDS		0xa2
-#define PFM_STOP		0xa3
-#define PFM_START		0xa4
-#define PFM_ENABLE		0xa5	/* unfreeze only */
-#define PFM_DISABLE		0xa6	/* freeze only */
-#define PFM_RESTART		0xcf
-#define PFM_CREATE_CONTEXT	0xa7
-#define PFM_DESTROY_CONTEXT	0xa8
 /*
- * Those 2 are just meant for debugging. I considered using sysctl() for
- * that but it is a little bit too pervasive. This solution is at least
- * self-contained.
+ * For PMUs which rely on the debug registers for some features, you must
+ * you must enable the following flag to activate the support for
+ * accessing the registers via the perfmonctl() interface.
  */
-#define PFM_DEBUG_ON		0xe0
-#define PFM_DEBUG_OFF		0xe1
-
-#define PFM_DEBUG_BASE		PFM_DEBUG_ON
-
+#ifdef CONFIG_ITANIUM
+#define PFM_PMU_USES_DBR	1
+#endif
 
 /*
- * perfmon API flags
+ * perfmon context states
  */
-#define PFM_FL_INHERIT_NONE	 0x00	/* never inherit a context across fork (default) */
-#define PFM_FL_INHERIT_ONCE	 0x01	/* clone pfm_context only once across fork() */
-#define PFM_FL_INHERIT_ALL	 0x02	/* always clone pfm_context across fork() */
-#define PFM_FL_SMPL_OVFL_NOBLOCK 0x04	/* do not block on sampling buffer overflow */
-#define PFM_FL_SYSTEM_WIDE	 0x08	/* create a system wide context */
-#define PFM_FL_EXCL_INTR	 0x10	/* exclude interrupt from system wide monitoring */
+#define PFM_CTX_DISABLED	0
+#define PFM_CTX_ENABLED		1
 
 /*
- * PMC API flags
+ * Reset register flags
  */
-#define PFM_REGFL_OVFL_NOTIFY	1		/* send notification on overflow */
+#define PFM_RELOAD_LONG_RESET	1
+#define PFM_RELOAD_SHORT_RESET	2
 
 /*
- * Private flags and masks
+ * Misc macros and definitions
  */
+#define PMU_FIRST_COUNTER	4
+
+#define PFM_IS_DISABLED() pmu_conf.pfm_is_disabled
+
+#define PMC_OVFL_NOTIFY(ctx, i)	((ctx)->ctx_soft_pmds[i].flags &  PFM_REGFL_OVFL_NOTIFY)
 #define PFM_FL_INHERIT_MASK	(PFM_FL_INHERIT_NONE|PFM_FL_INHERIT_ONCE|PFM_FL_INHERIT_ALL)
 
-#ifdef CONFIG_SMP
-#define cpu_is_online(i) (cpu_online_map & (1UL << i))
-#else
-#define cpu_is_online(i)	1
-#endif
+#define PMC_IS_IMPL(i)	  (i<pmu_conf.num_pmcs && pmu_conf.impl_regs[i>>6] & (1UL<< (i) %64))
+#define PMD_IS_IMPL(i)	  (i<pmu_conf.num_pmds &&  pmu_conf.impl_regs[4+(i>>6)] & (1UL<<(i) % 64))
+
+#define PMD_IS_COUNTING(i) (i >=0  && i < 256 && pmu_conf.counter_pmds[i>>6] & (1UL <<(i) % 64))
+#define PMC_IS_COUNTING(i) PMD_IS_COUNTING(i)
+
+#define IBR_IS_IMPL(k)	  (k<pmu_conf.num_ibrs)
+#define DBR_IS_IMPL(k)	  (k<pmu_conf.num_dbrs)
+
+#define PMC_IS_BTB(a)	  (((pfm_monitor_t *)(a))->pmc_es == PMU_BTB_EVENT)
+
+#define LSHIFT(x)		(1UL<<(x))
+#define PMM(x)			LSHIFT(x)
+#define PMC_IS_MONITOR(c)	((pmu_conf.monitor_pmcs[0] & PMM((c))) != 0)
+
+#define CTX_IS_ENABLED(c) 	((c)->ctx_flags.state == PFM_CTX_ENABLED)
+#define CTX_OVFL_NOBLOCK(c)	((c)->ctx_fl_block == 0)
+#define CTX_INHERIT_MODE(c)	((c)->ctx_fl_inherit)
+#define CTX_HAS_SMPL(c)		((c)->ctx_psb != NULL)
+#define CTX_USED_PMD(ctx,n) 	(ctx)->ctx_used_pmds[(n)>>6] |= 1UL<< ((n) % 64)
+
+#define CTX_USED_IBR(ctx,n) 	(ctx)->ctx_used_ibrs[(n)>>6] |= 1UL<< ((n) % 64)
+#define CTX_USED_DBR(ctx,n) 	(ctx)->ctx_used_dbrs[(n)>>6] |= 1UL<< ((n) % 64)
+#define CTX_USES_DBREGS(ctx)	(((pfm_context_t *)(ctx))->ctx_fl_using_dbreg==1)
+
+#define LOCK_CTX(ctx)	spin_lock(&(ctx)->ctx_lock)
+#define UNLOCK_CTX(ctx)	spin_unlock(&(ctx)->ctx_lock)
+
+#define SET_PMU_OWNER(t)    do { pmu_owners[smp_processor_id()].owner = (t); } while(0)
+#define PMU_OWNER()	    pmu_owners[smp_processor_id()].owner
+
+#define LOCK_PFS()	    spin_lock(&pfm_sessions.pfs_lock)
+#define UNLOCK_PFS()	    spin_unlock(&pfm_sessions.pfs_lock)
+
+#define PFM_REG_RETFLAG_SET(flags, val)	do { flags &= ~PFM_REG_RETFL_MASK; flags |= (val); } while(0)
+
+/*
+ * debugging
+ */
+#define DBprintk(a) \
+	do { \
+		if (pfm_debug_mode >0) { printk("%s.%d: CPU%d ", __FUNCTION__, __LINE__, smp_processor_id()); printk a; } \
+	} while (0)
 
-#define PMC_IS_IMPL(i)		(i < pmu_conf.num_pmcs && pmu_conf.impl_regs[i>>6] & (1<< (i&~(64-1))))
-#define PMD_IS_IMPL(i)		(i < pmu_conf.num_pmds &&  pmu_conf.impl_regs[4+(i>>6)] & (1<< (i&~(64-1))))
-#define PMD_IS_COUNTER(i)	(i>=PMU_FIRST_COUNTER && i < (PMU_FIRST_COUNTER+pmu_conf.max_counters))
-#define PMC_IS_COUNTER(i)	(i>=PMU_FIRST_COUNTER && i < (PMU_FIRST_COUNTER+pmu_conf.max_counters))
 
-/* This is the Itanium-specific PMC layout for counter config */
+/* 
+ * These are some helpful architected PMC and IBR/DBR register layouts
+ */
 typedef struct {
 	unsigned long pmc_plm:4;	/* privilege level mask */
 	unsigned long pmc_ev:1;		/* external visibility */
 	unsigned long pmc_oi:1;		/* overflow interrupt */
 	unsigned long pmc_pm:1;		/* privileged monitor */
 	unsigned long pmc_ig1:1;	/* reserved */
-	unsigned long pmc_es:7;		/* event select */
-	unsigned long pmc_ig2:1;	/* reserved */
-	unsigned long pmc_umask:4;	/* unit mask */
-	unsigned long pmc_thres:3;	/* threshold */
-	unsigned long pmc_ig3:1;	/* reserved (missing from table on p6-17) */
-	unsigned long pmc_ism:2;	/* instruction set mask */
-	unsigned long pmc_ig4:38;	/* reserved */
-} pmc_counter_reg_t;
-
-/* test for EAR/BTB configuration */
-#define PMU_DEAR_EVENT	0x67
-#define PMU_IEAR_EVENT	0x23
-#define PMU_BTB_EVENT	0x11
-
-#define PMC_IS_DEAR(a)		(((pmc_counter_reg_t *)(a))->pmc_es == PMU_DEAR_EVENT)
-#define PMC_IS_IEAR(a)		(((pmc_counter_reg_t *)(a))->pmc_es == PMU_IEAR_EVENT)
-#define PMC_IS_BTB(a)		(((pmc_counter_reg_t *)(a))->pmc_es == PMU_BTB_EVENT)
-
-/*
- * This header is at the beginning of the sampling buffer returned to the user.
- * It is exported as Read-Only at this point. It is directly followed with the
- * first record.
- */
-typedef struct {
-	int		hdr_version;		/* could be used to differentiate formats */
-	int		hdr_reserved;
-	unsigned long	hdr_entry_size;		/* size of one entry in bytes */
-	unsigned long	hdr_count;		/* how many valid entries */
-	unsigned long	hdr_pmds;		/* which pmds are recorded */
-} perfmon_smpl_hdr_t;
-
-/*
- * Header entry in the buffer as a header as follows.
- * The header is directly followed with the PMDS to saved in increasing index order:
- * PMD4, PMD5, .... How many PMDs are present is determined by the tool which must
- * keep track of it when generating the final trace file.
- */
-typedef struct {
-	int		pid;		/* identification of process */
-	int		cpu;		/* which cpu was used */
-	unsigned long	rate;		/* initial value of this counter */
-	unsigned long	stamp;		/* timestamp */
-	unsigned long	ip;		/* where did the overflow interrupt happened */
-	unsigned long	regs;		/* which registers overflowed (up to 64)*/
-} perfmon_smpl_entry_t;
+	unsigned long pmc_es:8;		/* event select */
+	unsigned long pmc_ig2:48;	/* reserved */
+} pfm_monitor_t;
 
 /*
  * There is one such data structure per perfmon context. It is used to describe the
- * sampling buffer. It is to be shared among siblings whereas the pfm_context isn't.
+ * sampling buffer. It is to be shared among siblings whereas the pfm_context 
+ * is not.
  * Therefore we maintain a refcnt which is incremented on fork().
- * This buffer is private to the kernel only the actual sampling buffer including its
- * header are exposed to the user. This construct allows us to export the buffer read-write,
- * if needed, without worrying about security problems.
- */
-typedef struct {
-	atomic_t		psb_refcnt;	/* how many users for the buffer */
-	int			reserved;
+ * This buffer is private to the kernel only the actual sampling buffer 
+ * including its header are exposed to the user. This construct allows us to 
+ * export the buffer read-write, if needed, without worrying about security 
+ * problems.
+ */
+typedef struct _pfm_smpl_buffer_desc {
+	spinlock_t		psb_lock;	/* protection lock */
+	unsigned long		psb_refcnt;	/* how many users for the buffer */
+	int			psb_flags;	/* bitvector of flags */
+
 	void			*psb_addr;	/* points to location of first entry */
 	unsigned long		psb_entries;	/* maximum number of entries */
 	unsigned long		psb_size;	/* aligned size of buffer */
-	unsigned long		psb_index;	/* next free entry slot */
+	unsigned long		psb_index;	/* next free entry slot XXX: must use the one in buffer */
 	unsigned long		psb_entry_size;	/* size of each entry including entry header */
 	perfmon_smpl_hdr_t	*psb_hdr;	/* points to sampling buffer header */
+
+	struct _pfm_smpl_buffer_desc *psb_next;	/* next psb, used for rvfreeing of psb_hdr */
+
 } pfm_smpl_buffer_desc_t;
 
+#define LOCK_PSB(p)	spin_lock(&(p)->psb_lock)
+#define UNLOCK_PSB(p)	spin_unlock(&(p)->psb_lock)
+
+#define PFM_PSB_VMA	0x1			/* a VMA is describing the buffer */
 
 /*
  * This structure is initialized at boot time and contains
@@ -180,126 +169,192 @@
 	unsigned long num_pmcs ;	/* highest PMC implemented (may have holes) */
 	unsigned long num_pmds;		/* highest PMD implemented (may have holes) */
 	unsigned long impl_regs[16];	/* buffer used to hold implememted PMC/PMD mask */
+	unsigned long num_ibrs;		/* number of instruction debug registers */
+	unsigned long num_dbrs;		/* number of data debug registers */
+	unsigned long monitor_pmcs[4];	/* which pmc are controlling monitors */
+	unsigned long counter_pmds[4];	/* which pmd are used as counters */
 } pmu_config_t;
 
-#define PERFMON_IS_DISABLED() pmu_conf.pfm_is_disabled
-
+/*
+ * 64-bit software counter structure
+ */
 typedef struct {
-	__u64		val;		/* virtual 64bit counter value */
-	__u64		ival;		/* initial value from user */
-	__u64		smpl_rval;	/* reset value on sampling overflow */
-	__u64		ovfl_rval;	/* reset value on overflow */
-	int		flags;		/* notify/do not notify */
+	u64 val;	/* virtual 64bit counter value */
+	u64 ival;	/* initial value from user */
+	u64 long_reset;	/* reset value on sampling overflow */
+	u64 short_reset;/* reset value on overflow */
+	u64 reset_pmds[4]; /* which other pmds to reset when this counter overflows */
+	int flags;	/* notify/do not notify */
 } pfm_counter_t;
-#define PMD_OVFL_NOTIFY(ctx, i)	((ctx)->ctx_pmds[i].flags &  PFM_REGFL_OVFL_NOTIFY)
 
 /*
- * perfmon context. One per process, is cloned on fork() depending on inheritance flags
+ * perfmon context. One per process, is cloned on fork() depending on 
+ * inheritance flags
  */
 typedef struct {
-	unsigned int inherit:2;	/* inherit mode */
-	unsigned int noblock:1;	/* block/don't block on overflow with notification */
-	unsigned int system:1;	/* do system wide monitoring */
-	unsigned int frozen:1;	/* pmu must be kept frozen on ctxsw in */
-	unsigned int exclintr:1;/* exlcude interrupts from system wide monitoring */
-	unsigned int reserved:26;
+	unsigned int state:1;		/* 0=disabled, 1=enabled */
+	unsigned int inherit:2;		/* inherit mode */
+	unsigned int block:1;		/* when 1, task will blocked on user notifications */
+	unsigned int system:1;		/* do system wide monitoring */
+	unsigned int frozen:1;		/* pmu must be kept frozen on ctxsw in */
+	unsigned int protected:1;	/* allow access to creator of context only */
+	unsigned int using_dbreg:1;	/* using range restrictions (debug registers) */
+	unsigned int reserved:24;
 } pfm_context_flags_t;
 
+/*
+ * perfmon context: encapsulates all the state of a monitoring session
+ * XXX: probably need to change layout
+ */
 typedef struct pfm_context {
+	pfm_smpl_buffer_desc_t	*ctx_psb;		/* sampling buffer, if any */
+	unsigned long		ctx_smpl_vaddr;		/* user level virtual address of smpl buffer */
 
-	pfm_smpl_buffer_desc_t	*ctx_smpl_buf;		/* sampling buffer descriptor, if any */
-	unsigned long		ctx_dear_counter;	/* which PMD holds D-EAR */
-	unsigned long		ctx_iear_counter;	/* which PMD holds I-EAR */
-	unsigned long		ctx_btb_counter;	/* which PMD holds BTB */
-
-	spinlock_t		ctx_notify_lock;
+	spinlock_t		ctx_lock;
 	pfm_context_flags_t	ctx_flags;		/* block/noblock */
-	int			ctx_notify_sig;		/* XXX: SIGPROF or other */
+
 	struct task_struct	*ctx_notify_task;	/* who to notify on overflow */
-	struct task_struct	*ctx_creator;		/* pid of creator (debug) */
+	struct task_struct	*ctx_owner;		/* pid of creator (debug) */
+
+	unsigned long		ctx_ovfl_regs[4];	/* which registers overflowed (notification) */
+	unsigned long		ctx_smpl_regs[4];	/* which registers to record on overflow */
 
-	unsigned long		ctx_ovfl_regs;		/* which registers just overflowed (notification) */
-	unsigned long		ctx_smpl_regs;		/* which registers to record on overflow */
+	struct semaphore	ctx_restart_sem;   	/* use for blocking notification mode */
 
-	struct semaphore	ctx_restart_sem; 	/* use for blocking notification mode */
+	unsigned long		ctx_used_pmds[4];	/* bitmask of used PMD (speedup ctxsw) */
+	unsigned long		ctx_saved_pmcs[4];	/* bitmask of PMC to save on ctxsw */
+	unsigned long		ctx_reload_pmcs[4];	/* bitmask of PMC to reload on ctxsw (SMP) */
 
-	unsigned long		ctx_used_pmds[4]; 	/* bitmask of used PMD (speedup ctxsw) */
-	unsigned long		ctx_used_pmcs[4]; 	/* bitmask of used PMC (speedup ctxsw) */
+	unsigned long		ctx_used_ibrs[4];	/* bitmask of used IBR (speedup ctxsw) */
+	unsigned long		ctx_used_dbrs[4];	/* bitmask of used DBR (speedup ctxsw) */
 
-	pfm_counter_t		ctx_pmds[IA64_NUM_PMD_COUNTERS]; /* XXX: size should be dynamic */
+	pfm_counter_t		ctx_soft_pmds[IA64_NUM_PMD_REGS]; /* XXX: size should be dynamic */
 
+	u64			ctx_saved_psr;		/* copy of psr used for lazy ctxsw */
+	unsigned long		ctx_saved_cpus_allowed;	/* copy of the task cpus_allowed (system wide) */
+	unsigned long		ctx_cpu;		/* cpu to which perfmon is applied (system wide) */
+
+	atomic_t		ctx_saving_in_progress;	/* flag indicating actual save in progress */
+	atomic_t		ctx_last_cpu;		/* CPU id of current or last CPU used */
 } pfm_context_t;
 
-#define CTX_USED_PMD(ctx,n) (ctx)->ctx_used_pmds[(n)>>6] |= 1<< ((n) % 64)
-#define CTX_USED_PMC(ctx,n) (ctx)->ctx_used_pmcs[(n)>>6] |= 1<< ((n) % 64)
+#define ctx_fl_inherit		ctx_flags.inherit
+#define ctx_fl_block		ctx_flags.block
+#define ctx_fl_system		ctx_flags.system
+#define ctx_fl_frozen		ctx_flags.frozen
+#define ctx_fl_protected	ctx_flags.protected
+#define ctx_fl_using_dbreg	ctx_flags.using_dbreg
+
+/*
+ * global information about all sessions
+ * mostly used to synchronize between system wide and per-process
+ */
+typedef struct {
+	spinlock_t		pfs_lock;		/* lock the structure */
 
-#define ctx_fl_inherit	ctx_flags.inherit
-#define ctx_fl_noblock	ctx_flags.noblock
-#define ctx_fl_system	ctx_flags.system
-#define ctx_fl_frozen	ctx_flags.frozen
-#define ctx_fl_exclintr	ctx_flags.exclintr
+	unsigned long		pfs_task_sessions;	/* number of per task sessions */
+	unsigned long		pfs_sys_sessions;	/* number of per system wide sessions */
+	unsigned long   	pfs_sys_use_dbregs;	  	/* incremented when a system wide session uses debug regs */
+	unsigned long   	pfs_ptrace_use_dbregs;	  /* incremented when a process uses debug regs */
+	struct task_struct	*pfs_sys_session[NR_CPUS];  /* point to task owning a system-wide session */
+} pfm_session_t;
 
-#define CTX_OVFL_NOBLOCK(c)	((c)->ctx_fl_noblock == 1)
-#define CTX_INHERIT_MODE(c)	((c)->ctx_fl_inherit)
-#define CTX_HAS_SMPL(c)		((c)->ctx_smpl_buf != NULL)
+/*
+ * structure used to pass argument to/from remote CPU 
+ * using IPI to check and possibly save the PMU context on SMP systems.
+ *
+ * not used in UP kernels
+ */
+typedef struct {
+	struct task_struct *task;	/* which task we are interested in */
+	int retval;			/* return value of the call: 0=you can proceed, 1=need to wait for completion */
+} pfm_smp_ipi_arg_t;
 
-static pmu_config_t pmu_conf;
+/*
+ * perfmon command descriptions
+ */
+typedef struct {
+	int		(*cmd_func)(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs);
+	int		cmd_flags;
+	unsigned int	cmd_narg;
+	size_t		cmd_argsize;
+} pfm_cmd_desc_t;
 
-/* for debug only */
-static int pfm_debug=0;	/* 0= nodebug, >0= debug output on */
+#define PFM_CMD_PID		0x1	/* command requires pid argument */
+#define PFM_CMD_ARG_READ	0x2	/* command must read argument(s) */
+#define PFM_CMD_ARG_WRITE	0x4	/* command must write argument(s) */
+#define PFM_CMD_CTX		0x8	/* command needs a perfmon context */
+#define PFM_CMD_NOCHK		0x10	/* command does not need to check task's state */
 
-#define DBprintk(a) \
-	do { \
-		if (pfm_debug >0) { printk(__FUNCTION__" %d: ", __LINE__); printk a; } \
-	} while (0);
+#define PFM_CMD_IDX(cmd)	(cmd)
+
+#define PFM_CMD_IS_VALID(cmd)	((PFM_CMD_IDX(cmd) >= 0) && (PFM_CMD_IDX(cmd) < PFM_CMD_COUNT) \
+				  && pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_func != NULL)
+
+#define PFM_CMD_USE_PID(cmd)	((pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_flags & PFM_CMD_PID) != 0)
+#define PFM_CMD_READ_ARG(cmd)	((pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_flags & PFM_CMD_ARG_READ) != 0)
+#define PFM_CMD_WRITE_ARG(cmd)	((pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_flags & PFM_CMD_ARG_WRITE) != 0)
+#define PFM_CMD_USE_CTX(cmd)	((pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_flags & PFM_CMD_CTX) != 0)
+#define PFM_CMD_CHK(cmd)	((pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_flags & PFM_CMD_NOCHK) == 0)
+
+#define PFM_CMD_ARG_MANY	-1 /* cannot be zero */
+#define PFM_CMD_NARG(cmd)	(pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_narg)
+#define PFM_CMD_ARG_SIZE(cmd)	(pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_argsize)
 
-static void ia64_reset_pmu(void);
 
 /*
- * structure used to pass information between the interrupt handler
- * and the tasklet.
+ * perfmon internal variables
  */
-typedef struct {
-	pid_t		to_pid;		/* which process to notify */
-	pid_t		from_pid;	/* which process is source of overflow */
-	int		sig;		/* with which signal */
-	unsigned long	bitvect;	/* which counters have overflowed */
-} notification_info_t;
+static pmu_config_t	pmu_conf; 	/* PMU configuration */
+static int		pfm_debug_mode;	/* 0= nodebug, >0= debug output on */
+static pfm_session_t	pfm_sessions;	/* global sessions information */
+static struct proc_dir_entry *perfmon_dir; /* for debug only */
+static unsigned long pfm_spurious_ovfl_intr_count; /* keep track of spurious ovfl interrupts */
+static unsigned long pfm_ovfl_intr_count; /* keep track of spurious ovfl interrupts */
+static unsigned long pfm_recorded_samples_count;
 
 
-typedef struct {
-	unsigned long pfs_proc_sessions;
-	unsigned long pfs_sys_session; /* can only be 0/1 */
-	unsigned long pfs_dfl_dcr;	/* XXX: hack */
-	unsigned int  pfs_pp;
-} pfm_session_t;
+static unsigned long reset_pmcs[IA64_NUM_PMC_REGS];	/* contains PAL reset values for PMCS */
+
+static void pfm_vm_close(struct vm_area_struct * area);
+static struct vm_operations_struct pfm_vm_ops={
+	close: pfm_vm_close
+};
 
-struct {
+/*
+ * keep track of task owning the PMU per CPU.
+ */
+static struct {
 	struct task_struct *owner;
 } ____cacheline_aligned pmu_owners[NR_CPUS];
 
 
-/* 
- * helper macros
- */
-#define SET_PMU_OWNER(t)	do { pmu_owners[smp_processor_id()].owner = (t); } while(0);
-#define PMU_OWNER()		pmu_owners[smp_processor_id()].owner
 
+/*
+ * forward declarations
+ */
+static void ia64_reset_pmu(struct task_struct *);
 #ifdef CONFIG_SMP
-#define PFM_CAN_DO_LAZY()	(smp_num_cpus==1 && pfs_info.pfs_sys_session==0)
-#else
-#define PFM_CAN_DO_LAZY()	(pfs_info.pfs_sys_session==0)
+static void pfm_fetch_regs(int cpu, struct task_struct *task, pfm_context_t *ctx);
 #endif
-
 static void pfm_lazy_save_regs (struct task_struct *ta);
 
-/* for debug only */
-static struct proc_dir_entry *perfmon_dir;
+static inline unsigned long
+pfm_read_soft_counter(pfm_context_t *ctx, int i)
+{
+	return ctx->ctx_soft_pmds[i].val + (ia64_get_pmd(i) & pmu_conf.perf_ovfl_val);
+}
 
-/*
- * XXX: hack to indicate that a system wide monitoring session is active
- */
-static pfm_session_t pfs_info;
+static inline void
+pfm_write_soft_counter(pfm_context_t *ctx, int i, unsigned long val)
+{
+	ctx->ctx_soft_pmds[i].val = val  & ~pmu_conf.perf_ovfl_val;
+	/*
+	 * writing to unimplemented part is ignore, so we do not need to
+	 * mask off top part
+	 */
+	ia64_set_pmd(i, val);
+}
 
 /*
  * finds the number of PM(C|D) registers given
@@ -324,10 +379,10 @@
  * Generates a unique (per CPU) timestamp
  */
 static inline unsigned long
-perfmon_get_stamp(void)
+pfm_get_stamp(void)
 {
 	/*
-	 * XXX: maybe find something more efficient
+	 * XXX: must find something more efficient
 	 */
 	return ia64_get_itc();
 }
@@ -353,80 +408,185 @@
 			}
 		}
 	}
-	DBprintk(("uv2kva(%lx-->%lx)\n", adr, ret));
+	DBprintk(("[%d] uv2kva(%lx-->%lx)\n", current->pid, adr, ret));
 	return ret;
 }
 
-
 /* Here we want the physical address of the memory.
  * This is used when initializing the contents of the
  * area and marking the pages as reserved.
  */
 static inline unsigned long
-kvirt_to_pa(unsigned long adr)
+pfm_kvirt_to_pa(unsigned long adr)
 {
 	__u64 pa = ia64_tpa(adr);
-	DBprintk(("kv2pa(%lx-->%lx)\n", adr, pa));
+	//DBprintk(("kv2pa(%lx-->%lx)\n", adr, pa));
 	return pa;
 }
 
+
 static void *
-rvmalloc(unsigned long size)
+pfm_rvmalloc(unsigned long size)
 {
 	void *mem;
 	unsigned long adr, page;
 
-	/* XXX: may have to revisit this part because
-	 * vmalloc() does not necessarily return a page-aligned buffer.
-	 * This maybe a security problem when mapped at user level
-	 */
 	mem=vmalloc(size);
 	if (mem) {
+		//printk("perfmon: CPU%d pfm_rvmalloc(%ld)=%p\n", smp_processor_id(), size, mem);
 		memset(mem, 0, size); /* Clear the ram out, no junk to the user */
 		adr=(unsigned long) mem;
 		while (size > 0) {
-			page = kvirt_to_pa(adr);
+			page = pfm_kvirt_to_pa(adr);
 			mem_map_reserve(virt_to_page(__va(page)));
-			adr+=PAGE_SIZE;
-			size-=PAGE_SIZE;
+			adr  += PAGE_SIZE;
+			size -= PAGE_SIZE;
 		}
 	}
 	return mem;
 }
 
 static void
-rvfree(void *mem, unsigned long size)
+pfm_rvfree(void *mem, unsigned long size)
 {
-	unsigned long adr, page;
+	unsigned long adr, page = 0;
 
 	if (mem) {
 		adr=(unsigned long) mem;
 		while (size > 0) {
-			page = kvirt_to_pa(adr);
+			page = pfm_kvirt_to_pa(adr);
 			mem_map_unreserve(virt_to_page(__va(page)));
 			adr+=PAGE_SIZE;
 			size-=PAGE_SIZE;
 		}
 		vfree(mem);
 	}
+	return;
+}
+
+/*
+ * This function gets called from mm/mmap.c:exit_mmap() only when there is a sampling buffer
+ * attached to the context AND the current task has a mapping for it, i.e., it is the original
+ * creator of the context.
+ *
+ * This function is used to remember the fact that the vma describing the sampling buffer
+ * has now been removed. It can only be called when no other tasks share the same mm context.
+ *
+ */
+static void 
+pfm_vm_close(struct vm_area_struct *vma)
+{
+	pfm_smpl_buffer_desc_t *psb = (pfm_smpl_buffer_desc_t *)vma->vm_private_data;
+
+	if (psb == NULL) {
+		printk("perfmon: psb is null in [%d]\n", current->pid);
+		return;
+	}
+	/*
+	 * Add PSB to list of buffers to free on release_thread() when no more users
+	 *
+	 * This call is safe because, once the count is zero is cannot be modified anymore.
+	 * This is not because there is no more user of the mm context, that the sampling
+	 * buffer is not being used anymore outside of this task. In fact, it can still
+	 * be accessed from within the kernel by another task (such as the monitored task).
+	 *
+	 * Therefore, we only move the psb into the list of buffers to free when we know
+	 * nobody else is using it.
+	 * The linked list if independent of the perfmon context, because in the case of
+	 * multi-threaded processes, the last thread may not have been involved with
+	 * monitoring however it will be the one removing the vma and it should therefore
+	 * also remove the sampling buffer. This buffer cannot be removed until the vma
+	 * is removed.
+	 *
+	 * This function cannot remove the buffer from here, because exit_mmap() must first
+	 * complete. Given that there is no other vma related callback in the generic code,
+	 * we have created on own with the linked list of sampling buffer to free which
+	 * is part of the thread structure. In release_thread() we check if the list is
+	 * empty. If not we call into perfmon to free the buffer and psb. That is the only
+	 * way to ensure a safe deallocation of the sampling buffer which works when
+	 * the buffer is shared between distinct processes or with multi-threaded programs.
+	 *
+	 * We need to lock the psb because the refcnt test and flag manipulation must
+	 * looked like an atomic operation vis a vis pfm_context_exit()
+	 */
+	LOCK_PSB(psb);
+
+	if (psb->psb_refcnt == 0) {
+
+		psb->psb_next = current->thread.pfm_smpl_buf_list;
+		current->thread.pfm_smpl_buf_list = psb;
+
+		DBprintk(("psb for [%d] smpl @%p size %ld inserted into list\n", 
+			current->pid, psb->psb_hdr, psb->psb_size));
+	}
+	DBprintk(("psb vma flag cleared for [%d] smpl @%p size %ld inserted into list\n", 
+			current->pid, psb->psb_hdr, psb->psb_size));
+
+	/*
+	 * indicate to pfm_context_exit() that the vma has been removed. 
+	 */
+	psb->psb_flags &= ~PFM_PSB_VMA;
+
+	UNLOCK_PSB(psb);
+}
+
+/*
+ * This function is called from pfm_destroy_context() and also from pfm_inherit()
+ * to explicitely remove the sampling buffer mapping from the user level address space.
+ */
+static int
+pfm_remove_smpl_mapping(struct task_struct *task)
+{
+	pfm_context_t *ctx = task->thread.pfm_context;
+	pfm_smpl_buffer_desc_t *psb;
+	int r;
+
+	/*
+	 * some sanity checks first
+	 */
+	if (ctx == NULL || task->mm == NULL || ctx->ctx_smpl_vaddr == 0 || ctx->ctx_psb == NULL) {
+		printk("perfmon: invalid context mm=%p\n", task->mm);
+		return -1;
+	}
+	psb = ctx->ctx_psb;	
+
+	down_write(&task->mm->mmap_sem);
+
+	r = do_munmap(task->mm, ctx->ctx_smpl_vaddr, psb->psb_size);
+
+	up_write(&task->mm->mmap_sem);
+	if (r !=0) {
+		printk("perfmon: pid %d unable to unmap sampling buffer @0x%lx size=%ld\n", 
+				task->pid, ctx->ctx_smpl_vaddr, psb->psb_size);
+	}
+	DBprintk(("[%d] do_unmap(0x%lx, %ld)=%d\n", 
+		task->pid, ctx->ctx_smpl_vaddr, psb->psb_size, r));
+
+	/* 
+	 * make sure we suppress all traces of this buffer
+	 * (important for pfm_inherit)
+	 */
+	ctx->ctx_smpl_vaddr = 0;
+
+	return 0;
 }
 
 static pfm_context_t *
 pfm_context_alloc(void)
 {
-	pfm_context_t *pfc;
+	pfm_context_t *ctx;
 
 	/* allocate context descriptor */
-	pfc = vmalloc(sizeof(*pfc));
-	if (pfc) memset(pfc, 0, sizeof(*pfc));
-
-	return pfc;
+	ctx = kmalloc(sizeof(pfm_context_t), GFP_KERNEL);
+	if (ctx) memset(ctx, 0, sizeof(pfm_context_t));
+	
+	return ctx;
 }
 
 static void
-pfm_context_free(pfm_context_t *pfc)
+pfm_context_free(pfm_context_t *ctx)
 {
-	if (pfc) vfree(pfc);
+	if (ctx) kfree(ctx);
 }
 
 static int
@@ -434,11 +594,13 @@
 {
 	unsigned long page;
 
+	DBprintk(("CPU%d buf=0x%lx addr=0x%lx size=%ld\n", smp_processor_id(), buf, addr, size));
+
 	while (size > 0) {
-		page = kvirt_to_pa(buf);
+		page = pfm_kvirt_to_pa(buf);
 
 		if (remap_page_range(addr, page, PAGE_SIZE, PAGE_SHARED)) return -ENOMEM;
-
+		
 		addr  += PAGE_SIZE;
 		buf   += PAGE_SIZE;
 		size  -= PAGE_SIZE;
@@ -458,7 +620,7 @@
 
 	for (i=0; i < size; i++, which++) res += hweight64(*which);
 
-	DBprintk((" res=%ld\n", res));
+	DBprintk(("weight=%ld\n", res));
 
 	return res;
 }
@@ -467,15 +629,16 @@
  * Allocates the sampling buffer and remaps it into caller's address space
  */
 static int
-pfm_smpl_buffer_alloc(pfm_context_t *ctx, unsigned long which_pmds, unsigned long entries, void **user_addr)
+pfm_smpl_buffer_alloc(pfm_context_t *ctx, unsigned long *which_pmds, unsigned long entries, 
+		      void **user_vaddr)
 {
 	struct mm_struct *mm = current->mm;
-	struct vm_area_struct *vma;
-	unsigned long addr, size, regcount;
+	struct vm_area_struct *vma = NULL;
+	unsigned long size, regcount;
 	void *smpl_buf;
 	pfm_smpl_buffer_desc_t *psb;
 
-	regcount = pfm_smpl_entry_size(&which_pmds, 1);
+	regcount = pfm_smpl_entry_size(which_pmds, 1);
 
 	/* note that regcount might be 0, in this case only the header for each
 	 * entry will be recorded.
@@ -488,133 +651,207 @@
 			  + entries * (sizeof(perfmon_smpl_entry_t) + regcount*sizeof(u64)));
 	/*
 	 * check requested size to avoid Denial-of-service attacks
-	 * XXX: may have to refine this test
+	 * XXX: may have to refine this test	
+	 * Check against address space limit.
+	 *
+	 * if ((mm->total_vm << PAGE_SHIFT) + len> current->rlim[RLIMIT_AS].rlim_cur) 
+	 * 	return -ENOMEM;
 	 */
 	if (size > current->rlim[RLIMIT_MEMLOCK].rlim_cur) return -EAGAIN;
 
-	/* find some free area in address space */
-	addr = get_unmapped_area(NULL, 0, size, 0, MAP_PRIVATE);
-	if (!addr) goto no_addr;
+	/*
+	 * We do the easy to undo allocations first.
+ 	 *
+	 * pfm_rvmalloc(), clears the buffer, so there is no leak
+	 */
+	smpl_buf = pfm_rvmalloc(size);
+	if (smpl_buf == NULL) {
+		DBprintk(("Can't allocate sampling buffer\n"));
+		return -ENOMEM;
+	}
+
+	DBprintk(("smpl_buf @%p\n", smpl_buf));
 
-	DBprintk((" entries=%ld aligned size=%ld, unmapped @0x%lx\n", entries, size, addr));
+	/* allocate sampling buffer descriptor now */
+	psb = kmalloc(sizeof(*psb), GFP_KERNEL);
+	if (psb == NULL) {
+		DBprintk(("Can't allocate sampling buffer descriptor\n"));
+		pfm_rvfree(smpl_buf, size);
+		return -ENOMEM;
+	}
 
 	/* allocate vma */
 	vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
-	if (!vma) goto no_vma;
-
-	/* XXX: see rvmalloc() for page alignment problem */
-	smpl_buf = rvmalloc(size);
-	if (smpl_buf == NULL) goto no_buffer;
-
-	DBprintk((" smpl_buf @%p\n", smpl_buf));
-
-	if (pfm_remap_buffer((unsigned long)smpl_buf, addr, size)) goto cant_remap;
-
-	/* allocate sampling buffer descriptor now */
-	psb = vmalloc(sizeof(*psb));
-	if (psb == NULL) goto no_buffer_desc;
+	if (!vma) {
+		DBprintk(("Cannot allocate vma\n"));
+		goto error;
+	}
+	/*
+	 * partially initialize the vma for the sampling buffer
+	 */
+	vma->vm_mm	     = mm;
+	vma->vm_flags	     = VM_READ| VM_MAYREAD |VM_RESERVED;
+	vma->vm_page_prot    = PAGE_READONLY; /* XXX may need to change */
+	vma->vm_ops	     = &pfm_vm_ops; /* necesarry to get the close() callback */
+	vma->vm_pgoff	     = 0;
+	vma->vm_file	     = NULL;
+	vma->vm_raend	     = 0;
+	vma->vm_private_data = psb;	/* information needed by the pfm_vm_close() function */
 
-	/* start with something clean */
-	memset(smpl_buf, 0x0, size);
+	/*
+	 * Now we have everything we need and we can initialize
+	 * and connect all the data structures
+	 */
 
 	psb->psb_hdr	 = smpl_buf;
-	psb->psb_addr    = (char *)smpl_buf+sizeof(perfmon_smpl_hdr_t); /* first entry */
+	psb->psb_addr    = ((char *)smpl_buf)+sizeof(perfmon_smpl_hdr_t); /* first entry */
 	psb->psb_size    = size; /* aligned size */
 	psb->psb_index   = 0;
 	psb->psb_entries = entries;
+	psb->psb_flags   = PFM_PSB_VMA; /* remember that there is a vma describing the buffer */
+	psb->psb_refcnt  = 1;
 
-	atomic_set(&psb->psb_refcnt, 1);
+	spin_lock_init(&psb->psb_lock);
 
+	/*
+	 * XXX: will need to do cacheline alignment to avoid false sharing in SMP mode and
+	 * multitask monitoring.
+	 */
 	psb->psb_entry_size = sizeof(perfmon_smpl_entry_t) + regcount*sizeof(u64);
 
-	DBprintk((" psb @%p entry_size=%ld hdr=%p addr=%p\n", (void *)psb,psb->psb_entry_size, (void *)psb->psb_hdr, (void *)psb->psb_addr));
-
-	/* initialize some of the fields of header */
-	psb->psb_hdr->hdr_version    = PFM_SMPL_HDR_VERSION;
-	psb->psb_hdr->hdr_entry_size = sizeof(perfmon_smpl_entry_t)+regcount*sizeof(u64);
-	psb->psb_hdr->hdr_pmds	     = which_pmds;
-
-	/* store which PMDS to record */
-	ctx->ctx_smpl_regs = which_pmds;
+	DBprintk(("psb @%p entry_size=%ld hdr=%p addr=%p\n", 
+		  (void *)psb,psb->psb_entry_size, (void *)psb->psb_hdr, 
+		  (void *)psb->psb_addr));
 
-	/* link to perfmon context */
-	ctx->ctx_smpl_buf  = psb;
+	/* initialize some of the fields of user visible buffer header */
+	psb->psb_hdr->hdr_version    = PFM_SMPL_VERSION;
+	psb->psb_hdr->hdr_entry_size = psb->psb_entry_size;
+	psb->psb_hdr->hdr_pmds[0]    = which_pmds[0];
 
 	/*
-	 * initialize the vma for the sampling buffer
+	 * Let's do the difficult operations next.
+	 *
+	 * now we atomically find some area in the address space and
+	 * remap the buffer in it.
 	 */
-	vma->vm_mm	  = mm;
-	vma->vm_start	  = addr;
-	vma->vm_end	  = addr + size;
-	vma->vm_flags	  = VM_READ|VM_MAYREAD;
-	vma->vm_page_prot = PAGE_READONLY; /* XXX may need to change */
-	vma->vm_ops	  = NULL;
-	vma->vm_pgoff	  = 0;
-	vma->vm_file	  = NULL;
-	vma->vm_raend	  = 0;
+	down_write(&current->mm->mmap_sem);
+
 
-	vma->vm_private_data = ctx;	/* link to pfm_context(not yet used) */
+	/* find some free area in address space, must have mmap sem held */
+	vma->vm_start = get_unmapped_area(NULL, 0, size, 0, MAP_PRIVATE|MAP_ANONYMOUS);
+	if (vma->vm_start == 0UL) {
+		DBprintk(("Cannot find unmapped area for size %ld\n", size));
+		up_write(&current->mm->mmap_sem);
+		goto error;
+	}
+	vma->vm_end = vma->vm_start + size;
+
+	DBprintk(("entries=%ld aligned size=%ld, unmapped @0x%lx\n", entries, size, vma->vm_start));
+		
+	/* can only be applied to current, need to have the mm semaphore held when called */
+	if (pfm_remap_buffer((unsigned long)smpl_buf, vma->vm_start, size)) {
+		DBprintk(("Can't remap buffer\n"));
+		up_write(&current->mm->mmap_sem);
+		goto error;
+	}
 
 	/*
-	 * now insert the vma in the vm list for the process
+	 * now insert the vma in the vm list for the process, must be
+	 * done with mmap lock held
 	 */
 	insert_vm_struct(mm, vma);
 
 	mm->total_vm  += size >> PAGE_SHIFT;
 
+	up_write(&current->mm->mmap_sem);
+
+	/* store which PMDS to record */
+	ctx->ctx_smpl_regs[0] = which_pmds[0];
+
+
+	/* link to perfmon context */
+	ctx->ctx_psb        = psb;
+
 	/*
-	 * that's the address returned to the user
+	 * keep track of user level virtual address 
 	 */
-	*user_addr = (void *)addr;
+	ctx->ctx_smpl_vaddr = *(unsigned long *)user_vaddr = vma->vm_start;
 
 	return 0;
 
-	/* outlined error handling */
-no_addr:
-	DBprintk(("Cannot find unmapped area for size %ld\n", size));
-	return -ENOMEM;
-no_vma:
-	DBprintk(("Cannot allocate vma\n"));
-	return -ENOMEM;
-cant_remap:
-	DBprintk(("Can't remap buffer\n"));
-	rvfree(smpl_buf, size);
-no_buffer:
-	DBprintk(("Can't allocate sampling buffer\n"));
-	kmem_cache_free(vm_area_cachep, vma);
-	return -ENOMEM;
-no_buffer_desc:
-	DBprintk(("Can't allocate sampling buffer descriptor\n"));
-	kmem_cache_free(vm_area_cachep, vma);
-	rvfree(smpl_buf, size);
+error:
+	pfm_rvfree(smpl_buf, size);
+	kfree(psb);
 	return -ENOMEM;
 }
 
+/*
+ * XXX: do something better here
+ */
+static int
+pfm_bad_permissions(struct task_struct *task)
+{
+	/* stolen from bad_signal() */
+	return (current->session != task->session)
+	    && (current->euid ^ task->suid) && (current->euid ^ task->uid)
+	    && (current->uid ^ task->suid) && (current->uid ^ task->uid);
+}
+
+
 static int
-pfx_is_sane(pfreq_context_t *pfx)
+pfx_is_sane(struct task_struct *task, pfarg_context_t *pfx)
 {
 	int ctx_flags;
+	int cpu;
 
 	/* valid signal */
-	//if (pfx->notify_sig < 1 || pfx->notify_sig >= _NSIG) return -EINVAL;
-	if (pfx->notify_sig !=0 && pfx->notify_sig != SIGPROF) return -EINVAL;
 
 	/* cannot send to process 1, 0 means do not notify */
-	if (pfx->notify_pid < 0 || pfx->notify_pid == 1) return -EINVAL;
-
-	ctx_flags = pfx->flags;
+	if (pfx->ctx_notify_pid == 1) {
+		DBprintk(("invalid notify_pid %d\n", pfx->ctx_notify_pid));
+		return -EINVAL;
+	}
+	ctx_flags = pfx->ctx_flags;
 
 	if (ctx_flags & PFM_FL_SYSTEM_WIDE) {
-#ifdef CONFIG_SMP
-		if (smp_num_cpus > 1) {
-			printk("perfmon: system wide monitoring on SMP not yet supported\n");
+		DBprintk(("cpu_mask=0x%lx\n", pfx->ctx_cpu_mask));
+		/*
+		 * cannot block in this mode 
+		 */
+		if (ctx_flags & PFM_FL_NOTIFY_BLOCK) {
+			DBprintk(("cannot use blocking mode when in system wide monitoring\n"));
 			return -EINVAL;
 		}
-#endif
-		if ((ctx_flags & PFM_FL_SMPL_OVFL_NOBLOCK) == 0) {
-			printk("perfmon: system wide monitoring cannot use blocking notification mode\n");
+		/*
+		 * must only have one bit set in the CPU mask
+		 */
+		if (hweight64(pfx->ctx_cpu_mask) != 1UL) {
+			DBprintk(("invalid CPU mask specified\n"));
+			return -EINVAL;
+		}
+		/*
+		 * and it must be a valid CPU
+		 */
+		cpu = ffs(pfx->ctx_cpu_mask);
+		if (cpu > smp_num_cpus) {
+			DBprintk(("CPU%d is not online\n", cpu));
+			return -EINVAL;
+		}
+		/*
+		 * check for pre-existing pinning, if conflicting reject
+		 */
+		if (task->cpus_allowed != ~0UL && (task->cpus_allowed & (1UL<<cpu)) == 0) {
+			DBprintk(("[%d] pinned on 0x%lx, mask for CPU%d \n", task->pid, 
+				task->cpus_allowed, cpu));
 			return -EINVAL;
 		}
+
+	} else {
+		/*
+		 * must provide a target for the signal in blocking mode even when
+		 * no counter is configured with PFM_FL_REG_OVFL_NOTIFY
+		 */
+		if ((ctx_flags & PFM_FL_NOTIFY_BLOCK) && pfx->ctx_notify_pid == 0) return -EINVAL;
 	}
 	/* probably more to add here */
 
@@ -622,68 +859,97 @@
 }
 
 static int
-pfm_context_create(int flags, perfmon_req_t *req)
+pfm_create_context(struct task_struct *task, pfm_context_t *ctx, void *req, int count, 
+		   struct pt_regs *regs)
 {
-	pfm_context_t *ctx;
-	struct task_struct *task = NULL;
-	perfmon_req_t tmp;
+	pfarg_context_t tmp;
 	void *uaddr = NULL;
-	int ret;
+	int ret, cpu = 0;
 	int ctx_flags;
-	pid_t pid;
+	pid_t notify_pid;
 
-	/* to go away */
-	if (flags) {
-		printk("perfmon: use context flags instead of perfmon() flags. Obsoleted API\n");
-	}
+	/* a context has already been defined */
+	if (ctx) return -EBUSY;
+
+	/*
+	 * not yet supported
+	 */
+	if (task != current) return -EINVAL;
 
 	if (copy_from_user(&tmp, req, sizeof(tmp))) return -EFAULT;
 
-	ret = pfx_is_sane(&tmp.pfr_ctx);
+	ret = pfx_is_sane(task, &tmp);
 	if (ret < 0) return ret;
 
-	ctx_flags = tmp.pfr_ctx.flags;
+	ctx_flags = tmp.ctx_flags;
+
+	ret =  -EBUSY;
+
+	LOCK_PFS();
 
 	if (ctx_flags & PFM_FL_SYSTEM_WIDE) {
+
+		/* at this point, we know there is at least one bit set */
+		cpu = ffs(tmp.ctx_cpu_mask) - 1;
+
+		DBprintk(("requesting CPU%d currently on CPU%d\n",cpu, smp_processor_id()));
+
+		if (pfm_sessions.pfs_task_sessions > 0) {
+			DBprintk(("system wide not possible, task_sessions=%ld\n", pfm_sessions.pfs_task_sessions));
+			goto abort;
+		}
+
+		if (pfm_sessions.pfs_sys_session[cpu]) {
+			DBprintk(("system wide not possible, conflicting session [%d] on CPU%d\n",pfm_sessions.pfs_sys_session[cpu]->pid, cpu));
+			goto abort;
+		}
+		pfm_sessions.pfs_sys_session[cpu] = task;
 		/*
-		 * XXX: This is not AT ALL SMP safe
+		 * count the number of system wide sessions
 		 */
-		if (pfs_info.pfs_proc_sessions > 0) return -EBUSY;
-		if (pfs_info.pfs_sys_session > 0) return -EBUSY;
+		pfm_sessions.pfs_sys_sessions++;
 
-		pfs_info.pfs_sys_session = 1;
-
-	} else if (pfs_info.pfs_sys_session >0) {
+	} else if (pfm_sessions.pfs_sys_sessions == 0) {
+		pfm_sessions.pfs_task_sessions++;
+	} else {
 		/* no per-process monitoring while there is a system wide session */
-		return -EBUSY;
-	} else
-		pfs_info.pfs_proc_sessions++;
+		goto abort;
+	}
+
+	UNLOCK_PFS();
+
+	ret = -ENOMEM;
 
 	ctx = pfm_context_alloc();
 	if (!ctx) goto error;
 
-	/* record the creator (debug only) */
-	ctx->ctx_creator = current;
+	/* record the creator (important for inheritance) */
+	ctx->ctx_owner = current;
+
+	notify_pid = tmp.ctx_notify_pid;
 
-	pid = tmp.pfr_ctx.notify_pid;
+	spin_lock_init(&ctx->ctx_lock);
 
-	spin_lock_init(&ctx->ctx_notify_lock);
+	if (notify_pid == current->pid) {
 
-	if (pid == current->pid) {
 		ctx->ctx_notify_task = task = current;
 		current->thread.pfm_context = ctx;
 
-		atomic_set(&current->thread.pfm_notifiers_check, 1);
+	} else if (notify_pid!=0) {
+		struct task_struct *notify_task;
 
-	} else if (pid!=0) {
 		read_lock(&tasklist_lock);
 
-		task = find_task_by_pid(pid);
-		if (task) {
+		notify_task = find_task_by_pid(notify_pid);
+
+		if (notify_task) {
+
+			ret = -EPERM;
+
 			/*
-		 	 * record who to notify
-		 	 */
-			ctx->ctx_notify_task = task;
+			 * check if we can send this task a signal
+			 */
+			if (pfm_bad_permissions(notify_task)) goto buffer_error;
 
 			/* 
 		 	 * make visible
@@ -702,7 +968,9 @@
 			 * task has been detached from the tasklist otherwise you are
 			 * exposed to race conditions.
 			 */
-			atomic_add(1, &task->thread.pfm_notifiers_check);
+			atomic_add(1, &ctx->ctx_notify_task->thread.pfm_notifiers_check);
+
+			ctx->ctx_notify_task = notify_task;
 		}
 		read_unlock(&tasklist_lock);
 	}
@@ -710,37 +978,48 @@
 	/*
 	 * notification process does not exist
 	 */
-	if (pid != 0 && task == NULL) {
+	if (notify_pid != 0 && ctx->ctx_notify_task == NULL) {
 		ret = -EINVAL;
 		goto buffer_error;
 	}
 
-	ctx->ctx_notify_sig = SIGPROF;	/* siginfo imposes a fixed signal */
+	if (tmp.ctx_smpl_entries) {
+		DBprintk(("sampling entries=%ld\n",tmp.ctx_smpl_entries));
 
-	if (tmp.pfr_ctx.smpl_entries) {
-		DBprintk((" sampling entries=%ld\n",tmp.pfr_ctx.smpl_entries));
-
-		ret = pfm_smpl_buffer_alloc(ctx, tmp.pfr_ctx.smpl_regs, 
-						 tmp.pfr_ctx.smpl_entries, &uaddr);
+		ret = pfm_smpl_buffer_alloc(ctx, tmp.ctx_smpl_regs, 
+						 tmp.ctx_smpl_entries, &uaddr);
 		if (ret<0) goto buffer_error;
 
-		tmp.pfr_ctx.smpl_vaddr = uaddr;
+		tmp.ctx_smpl_vaddr = uaddr;
 	}
 	/* initialization of context's flags */
-	ctx->ctx_fl_inherit  = ctx_flags & PFM_FL_INHERIT_MASK;
-	ctx->ctx_fl_noblock  = (ctx_flags & PFM_FL_SMPL_OVFL_NOBLOCK) ? 1 : 0;
-	ctx->ctx_fl_system   = (ctx_flags & PFM_FL_SYSTEM_WIDE) ? 1: 0;
-	ctx->ctx_fl_exclintr = (ctx_flags & PFM_FL_EXCL_INTR) ? 1: 0;
-	ctx->ctx_fl_frozen   = 0;
+	ctx->ctx_fl_inherit   = ctx_flags & PFM_FL_INHERIT_MASK;
+	ctx->ctx_fl_block     = (ctx_flags & PFM_FL_NOTIFY_BLOCK) ? 1 : 0;
+	ctx->ctx_fl_system    = (ctx_flags & PFM_FL_SYSTEM_WIDE) ? 1: 0;
+	ctx->ctx_fl_frozen    = 0;
+	/*
+	 * setting this flag to 0 here means, that the creator or the task that the
+	 * context is being attached are granted access. Given that a context can only
+	 * be created for the calling process this, in effect only allows the creator
+	 * to access the context. See pfm_protect() for more.
+	 */
+	ctx->ctx_fl_protected = 0;
+
+	/* for system wide mode only (only 1 bit set) */
+	ctx->ctx_cpu         = cpu;
+
+	atomic_set(&ctx->ctx_last_cpu,-1); /* SMP only, means no CPU */
 
 	/* 
 	 * Keep track of the pmds we want to sample
 	 * XXX: may be we don't need to save/restore the DEAR/IEAR pmds
 	 * but we do need the BTB for sure. This is because of a hardware
 	 * buffer of 1 only for non-BTB pmds.
+	 *
+	 * We ignore the unimplemented pmds specified by the user
 	 */
-	ctx->ctx_used_pmds[0] = tmp.pfr_ctx.smpl_regs;
-	ctx->ctx_used_pmcs[0] = 1; /* always save/restore PMC[0] */
+	ctx->ctx_used_pmds[0]  = tmp.ctx_smpl_regs[0] & pmu_conf.impl_regs[4];
+	ctx->ctx_saved_pmcs[0] = 1; /* always save/restore PMC[0] */
 
 	sema_init(&ctx->ctx_restart_sem, 0); /* init this semaphore to locked */
 
@@ -750,31 +1029,28 @@
 		goto buffer_error;
 	}
 
-	DBprintk((" context=%p, pid=%d notify_sig %d notify_task=%p\n",(void *)ctx, current->pid, ctx->ctx_notify_sig, ctx->ctx_notify_task));
-	DBprintk((" context=%p, pid=%d flags=0x%x inherit=%d noblock=%d system=%d\n",(void *)ctx, current->pid, ctx_flags, ctx->ctx_fl_inherit, ctx->ctx_fl_noblock, ctx->ctx_fl_system));
+	DBprintk(("context=%p, pid=%d notify_task=%p\n",
+			(void *)ctx, task->pid, ctx->ctx_notify_task));
+
+	DBprintk(("context=%p, pid=%d flags=0x%x inherit=%d block=%d system=%d\n", 
+			(void *)ctx, task->pid, ctx_flags, ctx->ctx_fl_inherit, 
+			ctx->ctx_fl_block, ctx->ctx_fl_system));
 
 	/*
 	 * when no notification is required, we can make this visible at the last moment
 	 */
-	if (pid == 0) current->thread.pfm_context = ctx;
-
+	if (notify_pid == 0) task->thread.pfm_context = ctx;
 	/*
-	 * by default, we always include interrupts for system wide
-	 * DCR.pp is set by default to zero by kernel  in cpu_init()
+	 * pin task to CPU and force reschedule on exit to ensure
+	 * that when back to user level the task runs on the designated
+	 * CPU.
 	 */
 	if (ctx->ctx_fl_system) {
-		if (ctx->ctx_fl_exclintr == 0) {
-			unsigned long dcr = ia64_get_dcr();
-
-			ia64_set_dcr(dcr|IA64_DCR_PP);
-			/*
-			* keep track of the kernel default value
-			 */
-			pfs_info.pfs_dfl_dcr = dcr;
-
-			DBprintk((" dcr.pp is set\n"));
-		}
-	} 
+		ctx->ctx_saved_cpus_allowed = task->cpus_allowed;
+		task->cpus_allowed = 1UL << cpu;
+		task->need_resched = 1;
+		DBprintk(("[%d] rescheduled allowed=0x%lx\n", task->pid,task->cpus_allowed));
+	}
 
 	return 0;
 
@@ -784,225 +1060,492 @@
 	/*
 	 * undo session reservation
 	 */
+	LOCK_PFS();
+
 	if (ctx_flags & PFM_FL_SYSTEM_WIDE) {
-		pfs_info.pfs_sys_session = 0;
+		pfm_sessions.pfs_sys_session[cpu] = NULL;
+		pfm_sessions.pfs_sys_sessions--;
 	} else {
-		pfs_info.pfs_proc_sessions--;
+		pfm_sessions.pfs_task_sessions--;
 	}
+abort:
+	UNLOCK_PFS();
+
 	return ret;
 }
 
 static void
-pfm_reset_regs(pfm_context_t *ctx)
+pfm_reset_regs(pfm_context_t *ctx, unsigned long *ovfl_regs, int flag)
 {
-	unsigned long mask = ctx->ctx_ovfl_regs;
-	int i, cnum;
+	unsigned long mask = ovfl_regs[0];
+	unsigned long reset_others = 0UL;
+	unsigned long val;
+	int i;
+
+	DBprintk(("masks=0x%lx\n", mask));
 
-	DBprintk((" ovfl_regs=0x%lx\n", mask));
 	/*
 	 * now restore reset value on sampling overflowed counters
 	 */
-	for(i=0, cnum=PMU_FIRST_COUNTER; i < pmu_conf.max_counters; i++, cnum++, mask >>= 1) {
+	mask >>= PMU_FIRST_COUNTER;
+	for(i = PMU_FIRST_COUNTER; mask; i++, mask >>= 1) {
 		if (mask & 0x1) {
-			DBprintk((" reseting PMD[%d]=%lx\n", cnum, ctx->ctx_pmds[i].smpl_rval & pmu_conf.perf_ovfl_val));
+			val  = flag == PFM_RELOAD_LONG_RESET ? 
+					ctx->ctx_soft_pmds[i].long_reset:
+					ctx->ctx_soft_pmds[i].short_reset;
+
+			reset_others |= ctx->ctx_soft_pmds[i].reset_pmds[0];
+
+			DBprintk(("[%d] %s reset soft_pmd[%d]=%lx\n", 
+			  	current->pid, 
+				flag == PFM_RELOAD_LONG_RESET ? "long" : "short", i, val));
 
 			/* upper part is ignored on rval */
-			ia64_set_pmd(cnum, ctx->ctx_pmds[i].smpl_rval);
+			pfm_write_soft_counter(ctx, i, val);
+		}
+	}
 
-			/*
-			 * we must reset BTB index (clears pmd16.full to make
-			 * sure we do not report the same branches twice.
-			 * The non-blocking case in handled in update_counters()
-			 */
-			if (cnum == ctx->ctx_btb_counter) {
-				DBprintk(("reseting PMD16\n"));
-				ia64_set_pmd(16, 0);
-			}
+	/*
+	 * Now take care of resetting the other registers
+	 */
+	for(i = 0; reset_others; i++, reset_others >>= 1) {
+
+		if ((reset_others & 0x1) == 0) continue;
+
+		val  = flag == PFM_RELOAD_LONG_RESET ? 
+					ctx->ctx_soft_pmds[i].long_reset:
+					ctx->ctx_soft_pmds[i].short_reset;
+
+		if (PMD_IS_COUNTING(i)) {
+			pfm_write_soft_counter(ctx, i, val);
+		} else {
+			ia64_set_pmd(i, val);
 		}
+
+		DBprintk(("[%d] %s reset_others pmd[%d]=%lx\n", 
+			  	current->pid, 
+				flag == PFM_RELOAD_LONG_RESET ? "long" : "short", i, val));
 	}
 	/* just in case ! */
-	ctx->ctx_ovfl_regs = 0;
+	ctx->ctx_ovfl_regs[0] = 0UL;
 }
 
 static int
-pfm_write_pmcs(struct task_struct *ta, perfmon_req_t *req, int count)
+pfm_write_pmcs(struct task_struct *ta, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
 {
 	struct thread_struct *th = &ta->thread;
-	pfm_context_t *ctx = th->pfm_context;
-	perfmon_req_t tmp;
-	unsigned long cnum;
+	pfarg_reg_t tmp, *req = (pfarg_reg_t *)arg;
+	unsigned int cnum;
 	int i;
+	int ret = 0, reg_retval = 0;
+
+	/* we don't quite support this right now */
+	if (ta != current) return -EINVAL;
+
+	if (!CTX_IS_ENABLED(ctx)) return -EINVAL;
 
 	/* XXX: ctx locking may be required here */
 
 	for (i = 0; i < count; i++, req++) {
 
+
 		if (copy_from_user(&tmp, req, sizeof(tmp))) return -EFAULT;
 
-		cnum = tmp.pfr_reg.reg_num;
+		cnum = tmp.reg_num;
 
-		/* XXX needs to check validity of the data maybe */
-		if (!PMC_IS_IMPL(cnum)) {
-			DBprintk((" invalid pmc[%ld]\n", cnum));
-			return -EINVAL;
+		/* 
+		 * we reject all non implemented PMC as well
+		 * as attempts to modify PMC[0-3] which are used
+		 * as status registers by the PMU
+		 */
+		if (!PMC_IS_IMPL(cnum) || cnum < 4) {
+			DBprintk(("pmc[%u] is unimplemented or invalid\n", cnum));
+			ret = -EINVAL;
+			goto abort_mission;
 		}
+		/*
+		 * A PMC used to configure monitors must be:
+		 * 	- system-wide session: privileged monitor
+		 * 	- per-task : user monitor
+		 * any other configuration is rejected.
+		 */
+		if (PMC_IS_MONITOR(cnum)) {
+			pfm_monitor_t *p = (pfm_monitor_t *)&tmp.reg_value;
 
-		if (PMC_IS_COUNTER(cnum)) {
+			DBprintk(("pmc[%u].pm = %d\n", cnum, p->pmc_pm));
 
+			if (ctx->ctx_fl_system ^ p->pmc_pm) {
+			//if ((ctx->ctx_fl_system == 1 && p->pmc_pm == 0)
+			 //  ||(ctx->ctx_fl_system == 0 && p->pmc_pm == 1)) {
+				ret = -EINVAL;
+				goto abort_mission;
+			}
 			/*
-			 * we keep track of EARS/BTB to speed up sampling later
+			 * enforce generation of overflow interrupt. Necessary on all
+			 * CPUs which do not implement 64-bit hardware counters.
 			 */
-			if (PMC_IS_DEAR(&tmp.pfr_reg.reg_value)) {
-				ctx->ctx_dear_counter = cnum;
-			} else if (PMC_IS_IEAR(&tmp.pfr_reg.reg_value)) {
-				ctx->ctx_iear_counter = cnum;
-			} else if (PMC_IS_BTB(&tmp.pfr_reg.reg_value)) {
-				ctx->ctx_btb_counter = cnum;
+			p->pmc_oi = 1;
+		}
+
+		if (PMC_IS_COUNTING(cnum)) {
+			if (tmp.reg_flags & PFM_REGFL_OVFL_NOTIFY) {
+				/*
+				 * must have a target for the signal
+				 */
+				if (ctx->ctx_notify_task == NULL) {
+					ret = -EINVAL;
+					goto abort_mission;
+				}
+
+				ctx->ctx_soft_pmds[cnum].flags |= PFM_REGFL_OVFL_NOTIFY;
 			}
-#if 0
-			if (tmp.pfr_reg.reg_flags & PFM_REGFL_OVFL_NOTIFY)
-				ctx->ctx_pmds[cnum - PMU_FIRST_COUNTER].flags |= PFM_REGFL_OVFL_NOTIFY;
-#endif
+			/*
+			 * copy reset vector
+			 */
+			ctx->ctx_soft_pmds[cnum].reset_pmds[0] = tmp.reg_reset_pmds[0];
+			ctx->ctx_soft_pmds[cnum].reset_pmds[1] = tmp.reg_reset_pmds[1];
+			ctx->ctx_soft_pmds[cnum].reset_pmds[2] = tmp.reg_reset_pmds[2];
+			ctx->ctx_soft_pmds[cnum].reset_pmds[3] = tmp.reg_reset_pmds[3];
+
+			/*
+			 * needed in case the user does not initialize the equivalent
+			 * PMD. Clearing is done in reset_pmu() so there is no possible
+			 * leak here.
+			 */
+			CTX_USED_PMD(ctx, cnum);
 		}
-		/* keep track of what we use */
-		CTX_USED_PMC(ctx, cnum);
-		ia64_set_pmc(cnum, tmp.pfr_reg.reg_value);
+abort_mission:
+		if (ret == -EINVAL) reg_retval = PFM_REG_RETFL_EINVAL;
 
-		DBprintk((" setting PMC[%ld]=0x%lx flags=0x%x used_pmcs=0%lx\n", cnum, tmp.pfr_reg.reg_value, ctx->ctx_pmds[cnum - PMU_FIRST_COUNTER].flags, ctx->ctx_used_pmcs[0]));
+		PFM_REG_RETFLAG_SET(tmp.reg_flags, reg_retval);
 
-	}
-	/*
-	 * we have to set this here event hough we haven't necessarily started monitoring
-	 * because we may be context switched out
-	 */
-	if (ctx->ctx_fl_system==0) th->flags |= IA64_THREAD_PM_VALID;
+		/*
+		 * update register return value, abort all if problem during copy.
+		 */
+		if (copy_to_user(req, &tmp, sizeof(tmp))) return -EFAULT;
 
-	return 0;
+		/*
+		 * if there was something wrong on this register, don't touch
+		 * the hardware at all and abort write request for others.
+		 *
+		 * On error, the user mut sequentially scan the table and the first
+		 * entry which has a return flag set is the one that caused the error.
+		 */
+		if (ret != 0) {
+			DBprintk(("[%d] pmc[%u]=0x%lx error %d\n",
+				  ta->pid, cnum, tmp.reg_value, reg_retval));
+			break;
+		}
+
+		/* 
+		 * We can proceed with this register!
+		 */
+		
+		/* 
+		 * keep copy the pmc, used for register reload
+		 */
+		th->pmc[cnum] = tmp.reg_value;
+
+		ia64_set_pmc(cnum, tmp.reg_value);
+
+		DBprintk(("[%d] pmc[%u]=0x%lx flags=0x%x save_pmcs=0%lx reload_pmcs=0x%lx\n", 
+			  ta->pid, cnum, tmp.reg_value, 
+			  ctx->ctx_soft_pmds[cnum].flags, 
+			  ctx->ctx_saved_pmcs[0], ctx->ctx_reload_pmcs[0]));
+
+	}
+	return ret;
 }
 
 static int
-pfm_write_pmds(struct task_struct *ta, perfmon_req_t *req, int count)
+pfm_write_pmds(struct task_struct *ta, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
 {
-	struct thread_struct *th = &ta->thread;
-	pfm_context_t *ctx = th->pfm_context;
-	perfmon_req_t tmp;
-	unsigned long cnum;
+	pfarg_reg_t tmp, *req = (pfarg_reg_t *)arg;
+	unsigned int cnum;
 	int i;
+	int ret = 0, reg_retval = 0;
+
+	/* we don't quite support this right now */
+	if (ta != current) return -EINVAL;
+
+	/* 
+	 * Cannot do anything before PMU is enabled 
+	 */
+	if (!CTX_IS_ENABLED(ctx)) return -EINVAL;
+
 
 	/* XXX: ctx locking may be required here */
 
 	for (i = 0; i < count; i++, req++) {
-		int k;
 
 		if (copy_from_user(&tmp, req, sizeof(tmp))) return -EFAULT;
 
-		cnum = tmp.pfr_reg.reg_num;
-
-		k = cnum - PMU_FIRST_COUNTER;
+		cnum = tmp.reg_num;
 
-		if (!PMD_IS_IMPL(cnum)) return -EINVAL;
+		if (!PMD_IS_IMPL(cnum)) {
+			ret = -EINVAL;
+			goto abort_mission;
+		}
 
 		/* update virtualized (64bits) counter */
-		if (PMD_IS_COUNTER(cnum)) {
-			ctx->ctx_pmds[k].ival = tmp.pfr_reg.reg_value;
-			ctx->ctx_pmds[k].val  = tmp.pfr_reg.reg_value & ~pmu_conf.perf_ovfl_val;
-			ctx->ctx_pmds[k].smpl_rval = tmp.pfr_reg.reg_smpl_reset;
-			ctx->ctx_pmds[k].ovfl_rval = tmp.pfr_reg.reg_ovfl_reset;
+		if (PMD_IS_COUNTING(cnum)) {
+			ctx->ctx_soft_pmds[cnum].ival = tmp.reg_value;
+			ctx->ctx_soft_pmds[cnum].val  = tmp.reg_value & ~pmu_conf.perf_ovfl_val;
+			ctx->ctx_soft_pmds[cnum].long_reset = tmp.reg_long_reset;
+			ctx->ctx_soft_pmds[cnum].short_reset = tmp.reg_short_reset;
+
+		}
+abort_mission:
+		if (ret == -EINVAL) reg_retval = PFM_REG_RETFL_EINVAL;
+
+		PFM_REG_RETFLAG_SET(tmp.reg_flags, reg_retval);
 
-			if (tmp.pfr_reg.reg_flags & PFM_REGFL_OVFL_NOTIFY)
-				ctx->ctx_pmds[cnum - PMU_FIRST_COUNTER].flags |= PFM_REGFL_OVFL_NOTIFY;
+		if (copy_to_user(req, &tmp, sizeof(tmp))) return -EFAULT;
+
+		/*
+		 * if there was something wrong on this register, don't touch
+		 * the hardware at all and abort write request for others.
+		 *
+		 * On error, the user mut sequentially scan the table and the first
+		 * entry which has a return flag set is the one that caused the error.
+		 */
+		if (ret != 0) {
+			DBprintk(("[%d] pmc[%u]=0x%lx error %d\n",
+				  ta->pid, cnum, tmp.reg_value, reg_retval));
+			break;
 		}
+
 		/* keep track of what we use */
 		CTX_USED_PMD(ctx, cnum);
 
 		/* writes to unimplemented part is ignored, so this is safe */
-		ia64_set_pmd(cnum, tmp.pfr_reg.reg_value);
+		ia64_set_pmd(cnum, tmp.reg_value);
 
 		/* to go away */
 		ia64_srlz_d();
-		DBprintk((" setting PMD[%ld]:  ovfl_notify=%d pmd.val=0x%lx pmd.ovfl_rval=0x%lx pmd.smpl_rval=0x%lx pmd=%lx used_pmds=0%lx\n",
-					cnum,
-					PMD_OVFL_NOTIFY(ctx, cnum - PMU_FIRST_COUNTER),
-					ctx->ctx_pmds[k].val,
-					ctx->ctx_pmds[k].ovfl_rval,
-					ctx->ctx_pmds[k].smpl_rval,
-					ia64_get_pmd(cnum) & pmu_conf.perf_ovfl_val,
-					ctx->ctx_used_pmds[0]));
+		DBprintk(("[%d] pmd[%u]: soft_pmd=0x%lx  short_reset=0x%lx "
+			  "long_reset=0x%lx hw_pmd=%lx notify=%c used_pmds=0x%lx reset_pmds=0x%lx\n",
+				ta->pid, cnum,
+				ctx->ctx_soft_pmds[cnum].val,
+				ctx->ctx_soft_pmds[cnum].short_reset,
+				ctx->ctx_soft_pmds[cnum].long_reset,
+				ia64_get_pmd(cnum) & pmu_conf.perf_ovfl_val,
+				PMC_OVFL_NOTIFY(ctx, cnum) ? 'Y':'N',
+				ctx->ctx_used_pmds[0],
+				ctx->ctx_soft_pmds[cnum].reset_pmds[0]));
 	}
-	/*
-	 * we have to set this here event hough we haven't necessarily started monitoring
-	 * because we may be context switched out
-	 */
-	if (ctx->ctx_fl_system==0) th->flags |= IA64_THREAD_PM_VALID;
-
-	return 0;
+	return ret;
 }
 
 static int
-pfm_read_pmds(struct task_struct *ta, perfmon_req_t *req, int count)
+pfm_read_pmds(struct task_struct *ta, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
 {
 	struct thread_struct *th = &ta->thread;
-	pfm_context_t *ctx = th->pfm_context;
 	unsigned long val=0;
-	perfmon_req_t tmp;
+	pfarg_reg_t tmp, *req = (pfarg_reg_t *)arg;
 	int i;
 
+	if (!CTX_IS_ENABLED(ctx)) return -EINVAL;
+
 	/*
 	 * XXX: MUST MAKE SURE WE DON"T HAVE ANY PENDING OVERFLOW BEFORE READING
-	 * This is required when the monitoring has been stoppped by user of kernel.
-	 * If ity is still going on, then that's fine because we a re not gauranteed
-	 * to return an accurate value in this case
+	 * This is required when the monitoring has been stoppped by user or kernel.
+	 * If it is still going on, then that's fine because we a re not guaranteed
+	 * to return an accurate value in this case.
 	 */
 
 	/* XXX: ctx locking may be required here */
 
+	DBprintk(("ctx_last_cpu=%d for [%d]\n", atomic_read(&ctx->ctx_last_cpu), ta->pid));
+
 	for (i = 0; i < count; i++, req++) {
-		unsigned long reg_val = ~0, ctx_val = ~0;
+		unsigned long reg_val = ~0UL, ctx_val = ~0UL;
 
 		if (copy_from_user(&tmp, req, sizeof(tmp))) return -EFAULT;
 
-		if (!PMD_IS_IMPL(tmp.pfr_reg.reg_num)) return -EINVAL;
+		if (!PMD_IS_IMPL(tmp.reg_num)) goto abort_mission;
 
-		if (PMD_IS_COUNTER(tmp.pfr_reg.reg_num)) {
-			if (ta == current){
-				val = ia64_get_pmd(tmp.pfr_reg.reg_num);
-			} else {
-				val = reg_val = th->pmd[tmp.pfr_reg.reg_num];
+		/*
+		 * If the task is not the current one, then we check if the
+		 * PMU state is still in the local live register due to lazy ctxsw.
+		 * If true, then we read directly from the registers.
+		 */
+		if (atomic_read(&ctx->ctx_last_cpu) == smp_processor_id()){
+			ia64_srlz_d();
+			val = reg_val = ia64_get_pmd(tmp.reg_num);
+			DBprintk(("reading pmd[%u]=0x%lx from hw\n", tmp.reg_num, val));
+		} else {
+#ifdef CONFIG_SMP
+			int cpu;
+			/*
+			 * for SMP system, the context may still be live on another
+			 * CPU so we need to fetch it before proceeding with the read
+			 * This call we only be made once for the whole loop because
+			 * of ctx_last_cpu becoming == -1.
+			 *
+			 * We cannot reuse ctx_last_cpu as it may change before we get to the
+			 * actual IPI call. In this case, we will do the call for nothing but
+			 * there is no way around it. The receiving side will simply do nothing.
+			 */
+			cpu = atomic_read(&ctx->ctx_last_cpu);
+			if (cpu != -1) {
+				DBprintk(("must fetch on CPU%d for [%d]\n", cpu, ta->pid));
+				pfm_fetch_regs(cpu, ta, ctx);
 			}
-			val &= pmu_conf.perf_ovfl_val;
+#endif
+			/* context has been saved */
+			val = reg_val = th->pmd[tmp.reg_num];
+		}
+		if (PMD_IS_COUNTING(tmp.reg_num)) {
 			/*
-			 * lower part of .val may not be zero, so we must be an addition because of
-			 * residual count (see update_counters).
+			 * XXX: need to check for overflow
 			 */
-			val += ctx_val = ctx->ctx_pmds[tmp.pfr_reg.reg_num - PMU_FIRST_COUNTER].val;
+
+			val &= pmu_conf.perf_ovfl_val;
+			val += ctx_val = ctx->ctx_soft_pmds[tmp.reg_num].val;
 		} else {
-			/* for now */
-			if (ta != current) return -EINVAL;
 
-			ia64_srlz_d();
-			val = ia64_get_pmd(tmp.pfr_reg.reg_num);
+			val = reg_val = ia64_get_pmd(tmp.reg_num);
 		}
-		tmp.pfr_reg.reg_value = val;
+		PFM_REG_RETFLAG_SET(tmp.reg_flags, 0);
+		tmp.reg_value = val;
 
-		DBprintk((" reading PMD[%ld]=0x%lx reg=0x%lx ctx_val=0x%lx pmc=0x%lx\n", 
-					tmp.pfr_reg.reg_num, val, reg_val, ctx_val, ia64_get_pmc(tmp.pfr_reg.reg_num)));
+		DBprintk(("read pmd[%u] soft_pmd=0x%lx reg=0x%lx pmc=0x%lx\n", 
+					tmp.reg_num, ctx_val, reg_val, 
+					ia64_get_pmc(tmp.reg_num)));
 
 		if (copy_to_user(req, &tmp, sizeof(tmp))) return -EFAULT;
 	}
 	return 0;
+abort_mission:
+	PFM_REG_RETFLAG_SET(tmp.reg_flags, PFM_REG_RETFL_EINVAL);
+	/* 
+	 * XXX: if this fails, we stick we the original failure, flag not updated!
+	 */
+	copy_to_user(req, &tmp, sizeof(tmp));
+	return -EINVAL;
+
+}
+
+#ifdef PFM_PMU_USES_DBR
+/*
+ * Only call this function when a process it trying to
+ * write the debug registers (reading is always allowed)
+ */
+int
+pfm_use_debug_registers(struct task_struct *task)
+{
+	pfm_context_t *ctx = task->thread.pfm_context;
+	int ret = 0;
+
+	DBprintk(("called for [%d]\n", task->pid));
+
+	/*
+	 * do it only once
+	 */
+	if (task->thread.flags & IA64_THREAD_DBG_VALID) return 0;
+
+	/*
+	 * Even on SMP, we do not need to use an atomic here because
+	 * the only way in is via ptrace() and this is possible only when the
+	 * process is stopped. Even in the case where the ctxsw out is not totally
+	 * completed by the time we come here, there is no way the 'stopped' process
+	 * could be in the middle of fiddling with the pfm_write_ibr_dbr() routine.
+	 * So this is always safe.
+	 */
+	if (ctx && ctx->ctx_fl_using_dbreg == 1) return -1;
+
+	/*
+	 * XXX: not pretty
+	 */
+	LOCK_PFS();
+
+	/*
+	 * We only allow the use of debug registers when there is no system
+	 * wide monitoring 
+	 * XXX: we could relax this by 
+	 */
+	if (pfm_sessions.pfs_sys_use_dbregs> 0)
+		ret = -1;
+	else
+		pfm_sessions.pfs_ptrace_use_dbregs++;
+
+	DBprintk(("ptrace_use_dbregs=%lu  sys_use_dbregs=%lu by [%d] ret = %d\n", 
+		  pfm_sessions.pfs_ptrace_use_dbregs, 
+		  pfm_sessions.pfs_sys_use_dbregs, 
+		  task->pid, ret));
+
+	UNLOCK_PFS();
+
+	return ret;
+}
+
+/*
+ * This function is called for every task that exits with the
+ * IA64_THREAD_DBG_VALID set. This indicates a task which was
+ * able to use the debug registers for debugging purposes via
+ * ptrace(). Therefore we know it was not using them for
+ * perfmormance monitoring, so we only decrement the number
+ * of "ptraced" debug register users to keep the count up to date
+ */
+int
+pfm_release_debug_registers(struct task_struct *task)
+{
+	int ret;
+
+	LOCK_PFS();
+	if (pfm_sessions.pfs_ptrace_use_dbregs == 0) {
+		printk("perfmon: invalid release for [%d] ptrace_use_dbregs=0\n", task->pid);
+		ret = -1;
+	}  else {
+		pfm_sessions.pfs_ptrace_use_dbregs--;
+		ret = 0;
+	}
+	UNLOCK_PFS();
+
+	return ret;
+}
+#else /* PFM_PMU_USES_DBR is true */
+/*
+ * in case, the PMU does not use the debug registers, these two functions are nops.
+ * The first function is called from arch/ia64/kernel/ptrace.c.
+ * The second function is called from arch/ia64/kernel/process.c.
+ */
+int
+pfm_use_debug_registers(struct task_struct *task)
+{
+	return 0;
+}
+int
+pfm_release_debug_registers(struct task_struct *task)
+{
+	return 0;
 }
+#endif /* PFM_PMU_USES_DBR */
 
 static int
-pfm_do_restart(struct task_struct *task)
+pfm_restart(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
+	 struct pt_regs *regs)
 {
-	struct thread_struct *th = &task->thread;
-	pfm_context_t *ctx = th->pfm_context;
 	void *sem = &ctx->ctx_restart_sem;
 
+	/* 
+	 * Cannot do anything before PMU is enabled 
+	 */
+	if (!CTX_IS_ENABLED(ctx)) return -EINVAL;
+
+
+	if (ctx->ctx_fl_frozen==0) {
+		printk("task %d without pmu_frozen set\n", task->pid);
+		return -EINVAL;
+	}
+
 	if (task == current) {
-		DBprintk((" restarting self %d frozen=%d \n", current->pid, ctx->ctx_fl_frozen));
+		DBprintk(("restarting self %d frozen=%d \n", current->pid, ctx->ctx_fl_frozen));
+
+		pfm_reset_regs(ctx, ctx->ctx_ovfl_regs, PFM_RELOAD_LONG_RESET);
 
-		pfm_reset_regs(ctx);
+		ctx->ctx_ovfl_regs[0] = 0UL;
 
 		/*
 		 * We ignore block/don't block because we never block
@@ -1011,26 +1554,36 @@
 		ctx->ctx_fl_frozen = 0;
 
 		if (CTX_HAS_SMPL(ctx)) {
-			ctx->ctx_smpl_buf->psb_hdr->hdr_count = 0;
-			ctx->ctx_smpl_buf->psb_index = 0;
+			ctx->ctx_psb->psb_hdr->hdr_count = 0;
+			ctx->ctx_psb->psb_index = 0;
 		}
 
-		/* pfm_reset_smpl_buffers(ctx,th->pfm_ovfl_regs);*/
-
 		/* simply unfreeze */
 		ia64_set_pmc(0, 0);
 		ia64_srlz_d();
 
 		return 0;
-	}
+	} 
+	/* restart on another task */
 
-	/* check if blocking */
+	/*
+	 * if blocking, then post the semaphore.
+	 * if non-blocking, then we ensure that the task will go into
+	 * pfm_overflow_must_block() before returning to user mode. 
+	 * We cannot explicitely reset another task, it MUST always
+	 * be done by the task itself. This works for system wide because
+	 * the tool that is controlling the session is doing "self-monitoring".
+	 *
+	 * XXX: what if the task never goes back to user?
+	 *
+	 */
 	if (CTX_OVFL_NOBLOCK(ctx) == 0) {
-		DBprintk((" unblocking %d \n", task->pid));
+		DBprintk(("unblocking %d \n", task->pid));
 		up(sem);
-		return 0;
+	} else {
+		task->thread.pfm_ovfl_block_reset = 1;
 	}
-
+#if 0
 	/*
 	 * in case of non blocking mode, then it's just a matter of
 	 * of reseting the sampling buffer (if any) index. The PMU
@@ -1041,281 +1594,719 @@
 	 * must reset the header count first
 	 */
 	if (CTX_HAS_SMPL(ctx)) {
-		DBprintk((" resetting sampling indexes for %d \n", task->pid));
-		ctx->ctx_smpl_buf->psb_hdr->hdr_count = 0;
-		ctx->ctx_smpl_buf->psb_index = 0;
+		DBprintk(("resetting sampling indexes for %d \n", task->pid));
+		ctx->ctx_psb->psb_hdr->hdr_count = 0;
+		ctx->ctx_psb->psb_index = 0;
 	}
-
+#endif
 	return 0;
 }
 
+#ifndef CONFIG_SMP
 /*
- * system-wide mode: propagate activation/desactivation throughout the tasklist
- *
- * XXX: does not work for SMP, of course
+ * On UP kernels, we do not need to constantly set the psr.pp bit
+ * when a task is scheduled. The psr.pp bit can only be changed in
+ * the kernel because of a user request. Given we are on a UP non preeemptive 
+ * kernel we know that no other task is running, so we cna simply update their
+ * psr.pp from their saved state. There is this no impact on the context switch
+ * code compared to the SMP case.
  */
 static void
-pfm_process_tasklist(int cmd)
+pfm_tasklist_toggle_pp(unsigned int val)
 {
 	struct task_struct *p;
 	struct pt_regs *regs;
 
+	DBprintk(("invoked by [%d] pp=%u\n", current->pid, val));
+
+	read_lock(&tasklist_lock);
+
 	for_each_task(p) {
-		regs = (struct pt_regs *)((unsigned long)p + IA64_STK_OFFSET);
+       		regs = (struct pt_regs *)((unsigned long) p + IA64_STK_OFFSET);
+
+		/*
+		 * position on pt_regs saved on stack on 1st entry into the kernel
+		 */
 		regs--;
-		ia64_psr(regs)->pp = cmd;
+
+		/*
+		 * update psr.pp
+		 */
+		ia64_psr(regs)->pp = val;
 	}
+	read_unlock(&tasklist_lock);
 }
+#endif
+
+
 
 static int
-do_perfmonctl (struct task_struct *task, int cmd, int flags, perfmon_req_t *req, int count, struct pt_regs *regs)
+pfm_stop(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
+	 struct pt_regs *regs)
 {
-	perfmon_req_t tmp;
-	struct thread_struct *th = &task->thread;
-	pfm_context_t *ctx = th->pfm_context;
-
-	memset(&tmp, 0, sizeof(tmp));
+	/* we don't quite support this right now */
+	if (task != current) return -EINVAL;
 
-	if (ctx == NULL && cmd != PFM_CREATE_CONTEXT && cmd < PFM_DEBUG_BASE) {
-		DBprintk((" PFM_WRITE_PMCS: no context for task %d\n", task->pid));
-		return -EINVAL;
-	}
+	/* 
+	 * Cannot do anything before PMU is enabled 
+	 */
+	if (!CTX_IS_ENABLED(ctx)) return -EINVAL;
 
-	switch (cmd) {
-		case PFM_CREATE_CONTEXT:
-			/* a context has already been defined */
-			if (ctx) return -EBUSY;
+	DBprintk(("[%d] fl_system=%d owner=%p current=%p\n",
+				current->pid,
+				ctx->ctx_fl_system, PMU_OWNER(),
+				current));
+	/* simply stop monitoring but not the PMU */
+	if (ctx->ctx_fl_system) {
 
-			/*
-			 * cannot directly create a context in another process
-			 */
-			if (task != current) return -EINVAL;
+		__asm__ __volatile__ ("rsm psr.pp;;"::: "memory");
 
-			if (req == NULL || count != 1) return -EINVAL;
+		/* disable dcr pp */
+		ia64_set_dcr(ia64_get_dcr() & ~IA64_DCR_PP);
 
-			if (!access_ok(VERIFY_READ, req, sizeof(struct perfmon_req_t)*count)) return -EFAULT;
+#ifdef CONFIG_SMP
+		local_cpu_data->pfm_dcr_pp  = 0;
+#else
+		pfm_tasklist_toggle_pp(0);
+#endif
 
-			return pfm_context_create(flags, req);
+		ia64_psr(regs)->pp = 0;
 
-		case PFM_WRITE_PMCS:
-			/* we don't quite support this right now */
-			if (task != current) return -EINVAL;
+	} else {
+		__asm__ __volatile__ ("rum psr.up;;"::: "memory");
 
-			if (!access_ok(VERIFY_READ, req, sizeof(struct perfmon_req_t)*count)) return -EFAULT;
+		ia64_psr(regs)->up = 0;
+	}
+	return 0;
+}
 
-			return pfm_write_pmcs(task, req, count);
+static int
+pfm_disable(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
+	   struct pt_regs *regs)
+{	
+	/* we don't quite support this right now */
+	if (task != current) return -EINVAL;
 
-		case PFM_WRITE_PMDS:
-			/* we don't quite support this right now */
-			if (task != current) return -EINVAL;
+	if (!CTX_IS_ENABLED(ctx)) return -EINVAL;
 
-			if (!access_ok(VERIFY_READ, req, sizeof(struct perfmon_req_t)*count)) return -EFAULT;
+	/*
+	 * stop monitoring, freeze PMU, and save state in context
+	 * this call will clear IA64_THREAD_PM_VALID for per-task sessions.
+	 */
+	pfm_flush_regs(task);
 
-			return pfm_write_pmds(task, req, count);
+	if (ctx->ctx_fl_system) {	
+		ia64_psr(regs)->pp = 0;
+	} else {
+		ia64_psr(regs)->up = 0;
+	}
+	/* 
+	 * goes back to default behavior 
+	 * no need to change live psr.sp because useless at the kernel level
+	 */
+	ia64_psr(regs)->sp = 1;
 
-		case PFM_START:
-			/* we don't quite support this right now */
-			if (task != current) return -EINVAL;
+	DBprintk(("enabling psr.sp for [%d]\n", current->pid));
 
-			if (PMU_OWNER()  && PMU_OWNER() != current && PFM_CAN_DO_LAZY()) pfm_lazy_save_regs(PMU_OWNER());
+	ctx->ctx_flags.state = PFM_CTX_DISABLED;
 
-			SET_PMU_OWNER(current);
+	return 0;
+}
 
-			/* will start monitoring right after rfi */
-			ia64_psr(regs)->up = 1;
-			ia64_psr(regs)->pp = 1;
 
-			if (ctx->ctx_fl_system) {
-				pfm_process_tasklist(1);
-				pfs_info.pfs_pp = 1;
-			}
 
-			/*
-			 * mark the state as valid.
-			 * this will trigger save/restore at context switch
-			 */
-			if (ctx->ctx_fl_system==0) th->flags |= IA64_THREAD_PM_VALID;
+static int
+pfm_destroy_context(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
+	 struct pt_regs *regs)
+{
+	/* we don't quite support this right now */
+	if (task != current) return -EINVAL;
 
-			ia64_set_pmc(0, 0);
-			ia64_srlz_d();
+	/*
+	 * if context was never enabled, then there is not much
+	 * to do
+	 */
+	if (!CTX_IS_ENABLED(ctx)) goto skipped_stop;
 
-			break;
+	/*
+	 * Disable context: stop monitoring, flush regs to software state (useless here), 
+	 * and freeze PMU
+	 * 
+	 * The IA64_THREAD_PM_VALID is cleared by pfm_flush_regs() called from pfm_disable()
+	 */
+	pfm_disable(task, ctx, arg, count, regs);
 
-		case PFM_ENABLE:
-			/* we don't quite support this right now */
-			if (task != current) return -EINVAL;
+	if (ctx->ctx_fl_system) {	
+		ia64_psr(regs)->pp = 0;
+	} else {
+		ia64_psr(regs)->up = 0;
+	}
 
-			if (PMU_OWNER()  && PMU_OWNER() != current && PFM_CAN_DO_LAZY()) pfm_lazy_save_regs(PMU_OWNER());
+	/* restore security level */
+	ia64_psr(regs)->sp = 1;
 
-			/* reset all registers to stable quiet state */
-			ia64_reset_pmu();
+skipped_stop:
+	/*
+	 * remove sampling buffer mapping, if any
+	 */
+	if (ctx->ctx_smpl_vaddr) pfm_remove_smpl_mapping(task);
 
-			/* make sure nothing starts */
-			ia64_psr(regs)->up = 0;
-			ia64_psr(regs)->pp = 0;
+	/* now free context and related state */
+	pfm_context_exit(task);
 
-			/* do it on the live register as well */
-			__asm__ __volatile__ ("rsm psr.pp|psr.pp;;"::: "memory");
+	return 0;
+}
 
-			SET_PMU_OWNER(current);
+/*
+ * does nothing at the moment
+ */
+static int
+pfm_unprotect_context(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
+	 struct pt_regs *regs)
+{
+	return 0;
+}
 
-			/*
-			 * mark the state as valid.
-			 * this will trigger save/restore at context switch
-			 */
-			if (ctx->ctx_fl_system==0) th->flags |= IA64_THREAD_PM_VALID;
+static int
+pfm_protect_context(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
+	 struct pt_regs *regs)
+{
+	DBprintk(("context from [%d] is protected\n", task->pid));
+	/*
+	 * from now on, only the creator of the context has access to it
+	 */
+	ctx->ctx_fl_protected = 1;
 
-			/* simply unfreeze */
-			ia64_set_pmc(0, 0);
-			ia64_srlz_d();
-			break;
+	/*
+	 * reinforce secure monitoring: cannot toggle psr.up
+	 */
+	ia64_psr(regs)->sp = 1;
 
-		case PFM_DISABLE:
-			/* we don't quite support this right now */
-			if (task != current) return -EINVAL;
+	return 0;
+}
 
-			/* simply freeze */
-			ia64_set_pmc(0, 1);
-			ia64_srlz_d();
-			/*
-			 * XXX: cannot really toggle IA64_THREAD_PM_VALID
-			 * but context is still considered valid, so any 
-			 * read request would return something valid. Same
-			 * thing when this task terminates (pfm_flush_regs()).
-			 */
-			break;
+static int
+pfm_debug(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
+	 struct pt_regs *regs)
+{
+	unsigned int mode = *(unsigned int *)arg;
 
-		case PFM_READ_PMDS:
-			if (!access_ok(VERIFY_READ, req, sizeof(struct perfmon_req_t)*count)) return -EFAULT;
-			if (!access_ok(VERIFY_WRITE, req, sizeof(struct perfmon_req_t)*count)) return -EFAULT;
-
-			return pfm_read_pmds(task, req, count);
-
-	      case PFM_STOP:
-			/* we don't quite support this right now */
-			if (task != current) return -EINVAL;
-
-			/* simply stop monitors, not PMU */
-			ia64_psr(regs)->up = 0;
-			ia64_psr(regs)->pp = 0;
-
-			if (ctx->ctx_fl_system) {
-				pfm_process_tasklist(0);
-				pfs_info.pfs_pp = 0;
-			}
+	pfm_debug_mode = mode == 0 ? 0 : 1;
 
-			break;
+	printk("perfmon debugging %s\n", pfm_debug_mode ? "on" : "off");
+
+	return 0;
+}
+
+#ifdef PFM_PMU_USES_DBR
+
+typedef struct {
+	unsigned long ibr_mask:56;
+	unsigned long ibr_plm:4;
+	unsigned long ibr_ig:3;
+	unsigned long ibr_x:1;
+} ibr_mask_reg_t;
+
+typedef struct {
+	unsigned long dbr_mask:56;
+	unsigned long dbr_plm:4;
+	unsigned long dbr_ig:2;
+	unsigned long dbr_w:1;
+	unsigned long dbr_r:1;
+} dbr_mask_reg_t;
+
+typedef union {
+	unsigned long  val;
+	ibr_mask_reg_t ibr;
+	dbr_mask_reg_t dbr;
+} dbreg_t;
+
+
+static int
+pfm_write_ibr_dbr(int mode, struct task_struct *task, void *arg, int count, struct pt_regs *regs)
+{
+	struct thread_struct *thread = &task->thread;
+	pfm_context_t *ctx = task->thread.pfm_context;
+	pfarg_dbreg_t tmp, *req = (pfarg_dbreg_t *)arg;
+	dbreg_t dbreg;
+	unsigned int rnum;
+	int first_time;
+	int i, ret = 0;
+
+	/*
+	 * for range restriction: psr.db must be cleared or the
+	 * the PMU will ignore the debug registers.
+	 *
+	 * XXX: may need more in system wide mode,
+	 * no task can have this bit set?
+	 */
+	if (ia64_psr(regs)->db == 1) return -EINVAL;
+
+
+	first_time = ctx->ctx_fl_using_dbreg == 0;
+
+	/*
+	 * check for debug registers in system wide mode
+	 *
+	 */
+	LOCK_PFS();
+	if (ctx->ctx_fl_system && first_time) {
+		if (pfm_sessions.pfs_ptrace_use_dbregs) 
+			ret = -EBUSY;
+		else
+			pfm_sessions.pfs_sys_use_dbregs++;
+	}
+	UNLOCK_PFS();
 
-	      case PFM_RESTART: /* temporary, will most likely end up as a PFM_ENABLE */
+	if (ret != 0) return ret;
 
-			if ((th->flags & IA64_THREAD_PM_VALID) == 0 && ctx->ctx_fl_system==0) {
-				printk(" PFM_RESTART not monitoring\n");
-				return -EINVAL;
+	if (ctx->ctx_fl_system) {
+		/* we mark ourselves as owner  of the debug registers */
+		ctx->ctx_fl_using_dbreg = 1;
+	} else {
+       		if (ctx->ctx_fl_using_dbreg == 0) {
+			ret= -EBUSY;
+			if ((thread->flags & IA64_THREAD_DBG_VALID) != 0) {
+				DBprintk(("debug registers already in use for [%d]\n", task->pid));
+				goto abort_mission;
+			}
+			/* we mark ourselves as owner  of the debug registers */
+			ctx->ctx_fl_using_dbreg = 1;
+
+			/* 
+			 * Given debug registers cannot be used for both debugging 
+			 * and performance monitoring at the same time, we reuse
+			 * the storage area to save and restore the registers on ctxsw.
+			 */
+			memset(task->thread.dbr, 0, sizeof(task->thread.dbr));
+			memset(task->thread.ibr, 0, sizeof(task->thread.ibr));
+
+			/*
+			 * clear hardware registers to make sure we don't leak
+			 * information and pick up stale state
+			 */
+			for (i=0; i < pmu_conf.num_ibrs; i++) {
+				ia64_set_ibr(i, 0UL);
 			}
-			if (CTX_OVFL_NOBLOCK(ctx) == 0 && ctx->ctx_fl_frozen==0) {
-				printk("task %d without pmu_frozen set\n", task->pid);
-				return -EINVAL;
+			for (i=0; i < pmu_conf.num_dbrs; i++) {
+				ia64_set_dbr(i, 0UL);
 			}
+		}
+	}
 
-			return pfm_do_restart(task); /* we only look at first entry */
+	ret = -EFAULT;
 
-	      case PFM_DESTROY_CONTEXT:
-			/* we don't quite support this right now */
-			if (task != current) return -EINVAL;
-
-			/* first stop monitors */
-			ia64_psr(regs)->up = 0;
-			ia64_psr(regs)->pp = 0;
+	/*
+	 * Now install the values into the registers
+	 */
+	for (i = 0; i < count; i++, req++) {
 
-			/* then freeze PMU */
-			ia64_set_pmc(0, 1);
-			ia64_srlz_d();
+		
+		if (copy_from_user(&tmp, req, sizeof(tmp))) goto abort_mission;
+		
+		rnum      = tmp.dbreg_num;
+		dbreg.val = tmp.dbreg_value;
+		
+		ret = -EINVAL;
 
-			/* don't save/restore on context switch */
-			if (ctx->ctx_fl_system ==0) task->thread.flags &= ~IA64_THREAD_PM_VALID;
+		if ((mode == 0 && !IBR_IS_IMPL(rnum)) || ((mode == 1) && !DBR_IS_IMPL(rnum))) {
+			DBprintk(("invalid register %u val=0x%lx mode=%d i=%d count=%d\n", 
+				  rnum, dbreg.val, mode, i, count));
 
-			SET_PMU_OWNER(NULL);
+			goto abort_mission;
+		}
 
-			/* now free context and related state */
-			pfm_context_exit(task);
-			break;
+		/*
+		 * make sure we do not install enabled breakpoint
+		 */
+		if (rnum & 0x1) {
+			if (mode == 0) 
+				dbreg.ibr.ibr_x = 0;
+			else
+				dbreg.dbr.dbr_r = dbreg.dbr.dbr_w = 0;
+		}
 
-	      case PFM_DEBUG_ON:
-			printk("perfmon debugging on\n");
-			pfm_debug = 1;
-			break;
+		/*
+		 * clear return flags and copy back to user
+		 *
+		 * XXX: fix once EAGAIN is implemented
+		 */
+		ret = -EFAULT;
 
-	      case PFM_DEBUG_OFF:
-			printk("perfmon debugging off\n");
-			pfm_debug = 0;
-			break;
+		PFM_REG_RETFLAG_SET(tmp.dbreg_flags, 0);
+
+		if (copy_to_user(req, &tmp, sizeof(tmp))) goto abort_mission;
+
+		/*
+		 * Debug registers, just like PMC, can only be modified
+		 * by a kernel call. Moreover, perfmon() access to those
+		 * registers are centralized in this routine. The hardware
+		 * does not modify the value of these registers, therefore,
+		 * if we save them as they are written, we can avoid having
+		 * to save them on context switch out. This is made possible
+		 * by the fact that when perfmon uses debug registers, ptrace()
+		 * won't be able to modify them concurrently.
+		 */
+		if (mode == 0) {
+			CTX_USED_IBR(ctx, rnum);
+
+			ia64_set_ibr(rnum, dbreg.val);
 
-	      default:
-			DBprintk((" UNknown command 0x%x\n", cmd));
+			thread->ibr[rnum] = dbreg.val;
+
+			DBprintk(("write ibr%u=0x%lx used_ibrs=0x%lx\n", rnum, dbreg.val, ctx->ctx_used_ibrs[0]));
+		} else {
+			CTX_USED_DBR(ctx, rnum);
+
+			ia64_set_dbr(rnum, dbreg.val);
+
+			thread->dbr[rnum] = dbreg.val;
+
+			DBprintk(("write dbr%u=0x%lx used_dbrs=0x%lx\n", rnum, dbreg.val, ctx->ctx_used_dbrs[0]));
+		}
+	}
+
+	return 0;
+
+abort_mission:
+	/*
+	 * in case it was our first attempt, we undo the global modifications
+	 */
+	if (first_time) {
+		LOCK_PFS();
+		if (ctx->ctx_fl_system) {
+			pfm_sessions.pfs_sys_use_dbregs--;
+		}
+		UNLOCK_PFS();
+		ctx->ctx_fl_using_dbreg = 0;
+	}
+	/*
+	 * install error return flag
+	 */
+	if (ret != -EFAULT) {
+		/*
+		 * XXX: for now we can only come here on EINVAL
+		 */
+		PFM_REG_RETFLAG_SET(tmp.dbreg_flags, PFM_REG_RETFL_EINVAL);
+		copy_to_user(req, &tmp, sizeof(tmp));
+	}
+	return ret;
+}
+
+static int
+pfm_write_ibrs(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
+	 struct pt_regs *regs)
+{	
+	/* we don't quite support this right now */
+	if (task != current) return -EINVAL;
+
+	if (!CTX_IS_ENABLED(ctx)) return -EINVAL;
+
+	return pfm_write_ibr_dbr(0, task, arg, count, regs);
+}
+
+static int
+pfm_write_dbrs(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
+	 struct pt_regs *regs)
+{	
+	/* we don't quite support this right now */
+	if (task != current) return -EINVAL;
+
+	if (!CTX_IS_ENABLED(ctx)) return -EINVAL;
+
+	return pfm_write_ibr_dbr(1, task, arg, count, regs);
+}
+
+#endif /* PFM_PMU_USES_DBR */
+
+static int
+pfm_get_features(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
+{
+	pfarg_features_t tmp;
+
+	memset(&tmp, 0, sizeof(tmp));
+
+	tmp.ft_version      = PFM_VERSION;
+	tmp.ft_smpl_version = PFM_SMPL_VERSION;
+
+	if (copy_to_user(arg, &tmp, sizeof(tmp))) return -EFAULT;
+
+	return 0;
+}
+
+static int
+pfm_start(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
+	  struct pt_regs *regs)
+{
+	/* we don't quite support this right now */
+	if (task != current) return -EINVAL;
+
+	/* 
+	 * Cannot do anything before PMU is enabled 
+	 */
+	if (!CTX_IS_ENABLED(ctx)) return -EINVAL;
+
+	DBprintk(("[%d] fl_system=%d owner=%p current=%p\n",
+				current->pid,
+				ctx->ctx_fl_system, PMU_OWNER(),
+				current));
+
+	if (PMU_OWNER() != task) {
+		printk("perfmon: pfm_start task [%d] not pmu owner\n", task->pid);
+		return -EINVAL;
+	}
+
+	if (ctx->ctx_fl_system) {
+		
+		/* enable dcr pp */
+		ia64_set_dcr(ia64_get_dcr()|IA64_DCR_PP);
+
+#ifdef CONFIG_SMP
+		local_cpu_data->pfm_dcr_pp  = 1;
+#else
+		pfm_tasklist_toggle_pp(1);
+#endif
+		ia64_psr(regs)->pp = 1;
+
+		__asm__ __volatile__ ("ssm psr.pp;;"::: "memory");
+
+	} else {
+		if ((task->thread.flags & IA64_THREAD_PM_VALID) == 0) {
+			printk("perfmon: pfm_start task flag not set for [%d]\n", task->pid);
 			return -EINVAL;
+		}
+		ia64_psr(regs)->up = 1;
+		__asm__ __volatile__ ("sum psr.up;;"::: "memory");
+	}
+	ia64_srlz_d();
+
+	return 0;
+}
+
+static int
+pfm_enable(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
+	   struct pt_regs *regs)
+{
+	/* we don't quite support this right now */
+	if (task != current) return -EINVAL;
+
+	if (ctx->ctx_fl_system == 0 && PMU_OWNER()  && PMU_OWNER() != current) 
+		pfm_lazy_save_regs(PMU_OWNER());
+
+	/* reset all registers to stable quiet state */
+	ia64_reset_pmu(task);
+
+	/* make sure nothing starts */
+	if (ctx->ctx_fl_system) {
+		ia64_psr(regs)->pp = 0;
+		ia64_psr(regs)->up = 0; /* just to make sure! */
+
+		__asm__ __volatile__ ("rsm psr.pp;;"::: "memory");
+
+#ifdef CONFIG_SMP
+		local_cpu_data->pfm_syst_wide = 1;
+		local_cpu_data->pfm_dcr_pp    = 0;
+#endif
+	} else {
+		/*
+		 * needed in case the task was a passive task during
+		 * a system wide session and now wants to have its own
+		 * session
+		 */
+		ia64_psr(regs)->pp = 0; /* just to make sure! */
+		ia64_psr(regs)->up = 0;
+
+		__asm__ __volatile__ ("rum psr.up;;"::: "memory");
+		/*
+		 * allow user control (user monitors only)
+		if (task  == ctx->ctx_owner) {
+		 */
+		{
+			DBprintk(("clearing psr.sp for [%d]\n", current->pid));
+			ia64_psr(regs)->sp = 0;
+		}
+		task->thread.flags |= IA64_THREAD_PM_VALID;
 	}
+
+	SET_PMU_OWNER(task);
+
+
+	ctx->ctx_flags.state = PFM_CTX_ENABLED;
+	atomic_set(&ctx->ctx_last_cpu, smp_processor_id());
+
+	/* simply unfreeze */
+	ia64_set_pmc(0, 0);
+	ia64_srlz_d();
+
 	return 0;
 }
 
 /*
- * XXX: do something better here
+ * functions MUST be listed in the increasing order of their index (see permfon.h)
  */
+static pfm_cmd_desc_t pfm_cmd_tab[]={
+/* 0  */{ NULL, 0, 0, 0}, /* not used */
+/* 1  */{ pfm_write_pmcs, PFM_CMD_PID|PFM_CMD_CTX|PFM_CMD_ARG_READ|PFM_CMD_ARG_WRITE, PFM_CMD_ARG_MANY, sizeof(pfarg_reg_t)}, 
+/* 2  */{ pfm_write_pmds, PFM_CMD_PID|PFM_CMD_CTX|PFM_CMD_ARG_READ, PFM_CMD_ARG_MANY, sizeof(pfarg_reg_t)},
+/* 3  */{ pfm_read_pmds, PFM_CMD_PID|PFM_CMD_CTX|PFM_CMD_ARG_READ|PFM_CMD_ARG_WRITE, PFM_CMD_ARG_MANY, sizeof(pfarg_reg_t)},
+/* 4  */{ pfm_stop, PFM_CMD_PID|PFM_CMD_CTX, 0, 0},
+/* 5  */{ pfm_start, PFM_CMD_PID|PFM_CMD_CTX, 0, 0},
+/* 6  */{ pfm_enable, PFM_CMD_PID|PFM_CMD_CTX, 0, 0},
+/* 7  */{ pfm_disable, PFM_CMD_PID|PFM_CMD_CTX, 0, 0},
+/* 8  */{ pfm_create_context, PFM_CMD_ARG_READ, 1, sizeof(pfarg_context_t)},
+/* 9  */{ pfm_destroy_context, PFM_CMD_PID|PFM_CMD_CTX, 0, 0},
+/* 10 */{ pfm_restart, PFM_CMD_PID|PFM_CMD_CTX|PFM_CMD_NOCHK, 0, 0},
+/* 11 */{ pfm_protect_context, PFM_CMD_PID|PFM_CMD_CTX, 0, 0},
+/* 12 */{ pfm_get_features, PFM_CMD_ARG_WRITE, 0, 0},
+/* 13 */{ pfm_debug, 0, 1, sizeof(unsigned int)},
+/* 14 */{ pfm_unprotect_context, PFM_CMD_PID|PFM_CMD_CTX, 0, 0},
+/* 15 */{ NULL, 0, 0, 0}, /* not used */
+/* 16 */{ NULL, 0, 0, 0}, /* not used */
+/* 17 */{ NULL, 0, 0, 0}, /* not used */
+/* 18 */{ NULL, 0, 0, 0}, /* not used */
+/* 19 */{ NULL, 0, 0, 0}, /* not used */
+/* 20 */{ NULL, 0, 0, 0}, /* not used */
+/* 21 */{ NULL, 0, 0, 0}, /* not used */
+/* 22 */{ NULL, 0, 0, 0}, /* not used */
+/* 23 */{ NULL, 0, 0, 0}, /* not used */
+/* 24 */{ NULL, 0, 0, 0}, /* not used */
+/* 25 */{ NULL, 0, 0, 0}, /* not used */
+/* 26 */{ NULL, 0, 0, 0}, /* not used */
+/* 27 */{ NULL, 0, 0, 0}, /* not used */
+/* 28 */{ NULL, 0, 0, 0}, /* not used */
+/* 29 */{ NULL, 0, 0, 0}, /* not used */
+/* 30 */{ NULL, 0, 0, 0}, /* not used */
+/* 31 */{ NULL, 0, 0, 0}, /* not used */
+#ifdef PFM_PMU_USES_DBR
+/* 32 */{ pfm_write_ibrs, PFM_CMD_PID|PFM_CMD_CTX|PFM_CMD_ARG_READ|PFM_CMD_ARG_WRITE, PFM_CMD_ARG_MANY, sizeof(pfarg_dbreg_t)},
+/* 33 */{ pfm_write_dbrs, PFM_CMD_PID|PFM_CMD_CTX|PFM_CMD_ARG_READ|PFM_CMD_ARG_WRITE, PFM_CMD_ARG_MANY, sizeof(pfarg_dbreg_t)}
+#endif
+};
+#define PFM_CMD_COUNT	(sizeof(pfm_cmd_tab)/sizeof(pfm_cmd_desc_t))
+
 static int
-perfmon_bad_permissions(struct task_struct *task)
+check_task_state(struct task_struct *task)
 {
-	/* stolen from bad_signal() */
-	return (current->session != task->session)
-	    && (current->euid ^ task->suid) && (current->euid ^ task->uid)
-	    && (current->uid ^ task->suid) && (current->uid ^ task->uid);
+	int ret = 0;
+#ifdef CONFIG_SMP
+	/* We must wait until the state has been completely
+	 * saved. There can be situations where the reader arrives before
+	 * after the task is marked as STOPPED but before pfm_save_regs()
+	 * is completed.
+	 */
+	for (;;) {
+
+		task_lock(task);
+		if (!task_has_cpu(task)) break;
+		task_unlock(task);
+
+		do {
+			if (task->state != TASK_ZOMBIE && task->state != TASK_STOPPED) return -EBUSY;
+			barrier();
+			cpu_relax();
+		} while (task_has_cpu(task));
+	}
+	task_unlock(task);
+#else
+	if (task->state != TASK_ZOMBIE && task->state != TASK_STOPPED) {
+		DBprintk(("warning [%d] not in stable state %ld\n", task->pid, task->state));
+		ret = -EBUSY;
+	}
+#endif
+	return ret;
 }
 
 asmlinkage int
-sys_perfmonctl (int pid, int cmd, int flags, perfmon_req_t *req, int count, long arg6, long arg7, long arg8, long stack)
+sys_perfmonctl (pid_t pid, int cmd, void *arg, int count, long arg5, long arg6, long arg7, 
+		long arg8, long stack)
 {
-	struct pt_regs *regs = (struct pt_regs *) &stack;
-	struct task_struct *child = current;
-	int ret = -ESRCH;
+	struct pt_regs *regs = (struct pt_regs *)&stack;
+	struct task_struct *task = current;
+	pfm_context_t *ctx = task->thread.pfm_context;
+	size_t sz;
+	int ret = -ESRCH, narg;
 
-	/* sanity check:
-	 *
-	 * ensures that we don't do bad things in case the OS
-	 * does not have enough storage to save/restore PMC/PMD
+	/* 
+	 * reject any call if perfmon was disabled at initialization time
 	 */
-	if (PERFMON_IS_DISABLED()) return -ENOSYS;
+	if (PFM_IS_DISABLED()) return -ENOSYS;
 
-	/* XXX: pid interface is going away in favor of pfm context */
-	if (pid != current->pid) {
-		read_lock(&tasklist_lock);
+	DBprintk(("cmd=%d idx=%d valid=%d narg=0x%x\n", cmd, PFM_CMD_IDX(cmd), 
+		  PFM_CMD_IS_VALID(cmd), PFM_CMD_NARG(cmd)));
 
-		child = find_task_by_pid(pid);
+	if (PFM_CMD_IS_VALID(cmd) == 0) return -EINVAL;
 
-		if (!child) goto abort_call;
+	/* ingore arguments when command has none */
+	narg = PFM_CMD_NARG(cmd);
+	if ((narg == PFM_CMD_ARG_MANY  && count == 0) || (narg > 0 && narg != count)) return -EINVAL;
 
-		ret = -EPERM;
+	sz = PFM_CMD_ARG_SIZE(cmd);
 
-		if (perfmon_bad_permissions(child)) goto abort_call;
+	if (PFM_CMD_READ_ARG(cmd) && !access_ok(VERIFY_READ, arg, sz*count)) return -EFAULT;
 
-		/*
-		 * XXX: need to do more checking here
+	if (PFM_CMD_WRITE_ARG(cmd) && !access_ok(VERIFY_WRITE, arg, sz*count)) return -EFAULT;
+
+	if (PFM_CMD_USE_PID(cmd))  {
+		/* 
+		 * XXX: may need to fine tune this one
 		 */
-		if (child->state != TASK_ZOMBIE && child->state != TASK_STOPPED) {
-			DBprintk((" warning process %d not in stable state %ld\n", pid, child->state));
+		if (pid < 2) return -EPERM;
+
+		if (pid != current->pid) {
+
+			read_lock(&tasklist_lock);
+
+			task = find_task_by_pid(pid);
+
+			if (!task) goto abort_call;
+
+			ret = -EPERM;
+
+			if (pfm_bad_permissions(task)) goto abort_call;
+
+			if (PFM_CMD_CHK(cmd)) {
+				ret = check_task_state(task);
+				if (ret != 0) goto abort_call;
+			}
+			ctx = task->thread.pfm_context;
 		}
+	} 
+
+	if (PFM_CMD_USE_CTX(cmd)) {
+		ret = -EINVAL;
+	       if (ctx == NULL) {
+			DBprintk(("no context for task %d\n", task->pid));
+			goto abort_call;
+	       }
+	       ret = -EPERM;
+	       /*
+		* we only grant access to the context if:
+		* 	- the caller is the creator of the context (ctx_owner)
+		*  OR   - the context is attached to the caller AND The context IS NOT 
+		*  	  in protected mode
+		*/
+	       if (ctx->ctx_owner != current && (ctx->ctx_fl_protected || task != current)) {
+				DBprintk(("context protected, no access for [%d]\n", task->pid));
+				goto abort_call;
+	       }
 	}
-	ret = do_perfmonctl(child, cmd, flags, req, count, regs);
+
+	ret = (*pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_func)(task, ctx, arg, count, regs);
 
 abort_call:
-	if (child != current) read_unlock(&tasklist_lock);
+	if (task != current) read_unlock(&tasklist_lock);
 
 	return ret;
 }
 
 #if __GNUC__ >= 3
 void asmlinkage
-pfm_block_on_overflow(void)
+pfm_ovfl_block_reset(u64 arg0, u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5, 
+		      u64 arg6, u64 arg7, long info)
 #else
 void asmlinkage
-pfm_block_on_overflow(u64 arg0, u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7)
+pfm_ovfl_block_reset(u64 arg0, u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5, 
+		      u64 arg6, u64 arg7, long info)
 #endif
 {
 	struct thread_struct *th = &current->thread;
@@ -1323,32 +2314,22 @@
 	int ret;
 
 	/*
-	 * NO matter what notify_pid is,
-	 * we clear overflow, won't notify again
+	 * clear the flag, to make sure we won't get here
+	 * again
 	 */
-	th->pfm_must_block = 0;
+	th->pfm_ovfl_block_reset = 0;
 
 	/*
 	 * do some sanity checks first
 	 */
 	if (!ctx) {
-		printk("perfmon: process %d has no PFM context\n", current->pid);
-		return;
-	}
-	if (ctx->ctx_notify_task == 0) {
-		printk("perfmon: process %d has no task to notify\n", current->pid);
+		printk("perfmon: [%d] has no PFM context\n", current->pid);
 		return;
 	}
 
-	DBprintk((" current=%d task=%d\n", current->pid, ctx->ctx_notify_task->pid));
-
-	/* should not happen */
-	if (CTX_OVFL_NOBLOCK(ctx)) {
-		printk("perfmon: process %d non-blocking ctx should not be here\n", current->pid);
-		return;
-	}
+	if (CTX_OVFL_NOBLOCK(ctx)) goto non_blocking;
 
-	DBprintk((" CPU%d %d before sleep\n", smp_processor_id(), current->pid));
+	DBprintk(("[%d] before sleeping\n", current->pid));
 
 	/*
 	 * may go through without blocking on SMP systems
@@ -1356,12 +2337,14 @@
 	 */
 	ret = down_interruptible(&ctx->ctx_restart_sem);
 
-	DBprintk((" CPU%d %d after sleep ret=%d\n", smp_processor_id(), current->pid, ret));
+	DBprintk(("[%d] after sleeping ret=%d\n", current->pid, ret));
 
 	/*
 	 * in case of interruption of down() we don't restart anything
 	 */
 	if (ret >= 0) {
+
+non_blocking:
 		/* we reactivate on context switch */
 		ctx->ctx_fl_frozen = 0;
 		/*
@@ -1369,19 +2352,19 @@
 		 * use the local reference
 		 */
 
-		pfm_reset_regs(ctx);
+		pfm_reset_regs(ctx, ctx->ctx_ovfl_regs, PFM_RELOAD_LONG_RESET);
+
+		ctx->ctx_ovfl_regs[0] = 0UL;
 
 		/*
 		 * Unlock sampling buffer and reset index atomically
 		 * XXX: not really needed when blocking
 		 */
 		if (CTX_HAS_SMPL(ctx)) {
-			ctx->ctx_smpl_buf->psb_hdr->hdr_count = 0;
-			ctx->ctx_smpl_buf->psb_index = 0;
+			ctx->ctx_psb->psb_hdr->hdr_count = 0;
+			ctx->ctx_psb->psb_index = 0;
 		}
 
-		DBprintk((" CPU%d %d unfreeze PMU\n", smp_processor_id(), current->pid));
-
 		ia64_set_pmc(0, 0);
 		ia64_srlz_d();
 
@@ -1390,23 +2373,111 @@
 }
 
 /*
+ * This function will record an entry in the sampling if it is not full already.
+ * Return:
+ * 	0 : buffer is not full (did not BECOME full: still space or was already full)
+ * 	1 : buffer is full (recorded the last entry)
+ */
+static int
+pfm_record_sample(struct task_struct *task, pfm_context_t *ctx, unsigned long ovfl_mask, struct pt_regs *regs)
+{
+	pfm_smpl_buffer_desc_t *psb = ctx->ctx_psb;
+	unsigned long *e, m, idx;
+	perfmon_smpl_entry_t *h;
+	int j;
+
+
+pfm_recorded_samples_count++;
+	idx = ia64_fetch_and_add(1, &psb->psb_index);
+	DBprintk(("recording index=%ld entries=%ld\n", idx-1, psb->psb_entries));
+
+	/*
+	* XXX: there is a small chance that we could run out on index before resetting
+	* but index is unsigned long, so it will take some time.....
+	* We use > instead of == because fetch_and_add() is off by one (see below)
+	*
+	* This case can happen in non-blocking mode or with multiple processes.
+	* For non-blocking, we need to reload and continue.
+	 */
+	if (idx > psb->psb_entries) return 0;
+
+	/* first entry is really entry 0, not 1 caused by fetch_and_add */
+	idx--;
+
+	h = (perfmon_smpl_entry_t *)(((char *)psb->psb_addr) + idx*(psb->psb_entry_size));
+
+	/*
+	 * initialize entry header
+	 */
+	h->pid  = task->pid;
+	h->cpu  = smp_processor_id();
+	h->rate = 0; /* XXX: add the sampling rate used here */
+	h->ip   = regs ? regs->cr_iip : 0x0;	/* where did the fault happened */
+	h->regs = ovfl_mask; 			/* which registers overflowed */
+
+	/* guaranteed to monotonically increase on each cpu */
+	h->stamp  = pfm_get_stamp();
+	h->period = 0UL; /* not yet used */
+
+	/* position for first pmd */
+	e = (unsigned long *)(h+1);
+
+	/*
+	 * selectively store PMDs in increasing index number
+	 */
+	m = ctx->ctx_smpl_regs[0];
+	for (j=0; m; m >>=1, j++) {
+
+		if ((m & 0x1) == 0) continue;
+
+		if (PMD_IS_COUNTING(j)) {
+			*e  =  pfm_read_soft_counter(ctx, j);
+			/* check if this pmd overflowed as well */
+			*e +=  ovfl_mask & (1UL<<j) ? 1 + pmu_conf.perf_ovfl_val : 0;
+		} else {
+			*e = ia64_get_pmd(j); /* slow */
+		}
+		DBprintk(("e=%p pmd%d =0x%lx\n", (void *)e, j, *e));
+		e++;
+	}
+	/*
+	 * make the new entry visible to user, needs to be atomic
+	 */
+	ia64_fetch_and_add(1, &psb->psb_hdr->hdr_count);
+
+	DBprintk(("index=%ld entries=%ld hdr_count=%ld\n", 
+				idx, psb->psb_entries, psb->psb_hdr->hdr_count));
+	/* 
+	 * sampling buffer full ? 
+	 */
+	if (idx == (psb->psb_entries-1)) {
+		DBprintk(("sampling buffer full\n"));
+		/*
+		 * XXX: must reset buffer in blocking mode and lost notified
+		 */
+		return 1;
+	}
+	return 0;
+}
+
+/*
  * main overflow processing routine.
  * it can be called from the interrupt path or explicitely during the context switch code
  * Return:
  *	new value of pmc[0]. if 0x0 then unfreeze, else keep frozen
  */
-unsigned long
-update_counters (struct task_struct *task, u64 pmc0, struct pt_regs *regs)
+static unsigned long
+pfm_overflow_handler(struct task_struct *task, u64 pmc0, struct pt_regs *regs)
 {
-	unsigned long mask, i, cnum;
-	struct thread_struct *th;
+	unsigned long mask;
+	struct thread_struct *t;
 	pfm_context_t *ctx;
-	unsigned long bv = 0;
+	unsigned long old_val;
+	unsigned long ovfl_notify = 0UL, ovfl_pmds = 0UL;
+	int i;
 	int my_cpu = smp_processor_id();
-	int ret = 1, buffer_is_full = 0;
-	int ovfl_has_long_recovery, can_notify, need_reset_pmd16=0;
+	int ret = 1;
 	struct siginfo si;
-
 	/*
 	 * It is never safe to access the task for which the overflow interrupt is destinated
 	 * using the current variable as the interrupt may occur in the middle of a context switch
@@ -1421,233 +2492,151 @@
 	 */
 
 	if (task == NULL) {
-		DBprintk((" owners[%d]=NULL\n", my_cpu));
+		DBprintk(("owners[%d]=NULL\n", my_cpu));
 		return 0x1;
 	}
-	th  = &task->thread;
-	ctx = th->pfm_context;
+	t   = &task->thread;
+	ctx = task->thread.pfm_context;
+
+	if (!ctx) {
+		printk("perfmon: Spurious overflow interrupt: process %d has no PFM context\n", 
+			task->pid);
+		return 0;
+	}
 
 	/*
 	 * XXX: debug test
 	 * Don't think this could happen given upfront tests
 	 */
-	if ((th->flags & IA64_THREAD_PM_VALID) == 0 && ctx->ctx_fl_system == 0) {
-		printk("perfmon: Spurious overflow interrupt: process %d not using perfmon\n", task->pid);
+	if ((t->flags & IA64_THREAD_PM_VALID) == 0 && ctx->ctx_fl_system == 0) {
+		printk("perfmon: Spurious overflow interrupt: process %d not using perfmon\n", 
+			task->pid);
 		return 0x1;
 	}
-	if (!ctx) {
-		printk("perfmon: Spurious overflow interrupt: process %d has no PFM context\n", task->pid);
-		return 0;
-	}
-
 	/*
 	 * sanity test. Should never happen
 	 */
-	if ((pmc0 & 0x1 )== 0) {
-		printk("perfmon: pid %d pmc0=0x%lx assumption error for freeze bit\n", task->pid, pmc0);
+	if ((pmc0 & 0x1) == 0) {
+		printk("perfmon: pid %d pmc0=0x%lx assumption error for freeze bit\n", 
+			task->pid, pmc0);
 		return 0x0;
 	}
 
 	mask = pmc0 >> PMU_FIRST_COUNTER;
 
-	DBprintk(("pmc0=0x%lx pid=%d owner=%d iip=0x%lx, ctx is in %s mode used_pmds=0x%lx used_pmcs=0x%lx\n", 
-				pmc0, task->pid, PMU_OWNER()->pid, regs->cr_iip, 
-				CTX_OVFL_NOBLOCK(ctx) ? "NO-BLOCK" : "BLOCK",
-				ctx->ctx_used_pmds[0],
-				ctx->ctx_used_pmcs[0]));
+	DBprintk(("pmc0=0x%lx pid=%d iip=0x%lx, %s"
+		  " mode used_pmds=0x%lx save_pmcs=0x%lx reload_pmcs=0x%lx\n", 
+			pmc0, task->pid, (regs ? regs->cr_iip : 0), 
+			CTX_OVFL_NOBLOCK(ctx) ? "nonblocking" : "blocking",
+			ctx->ctx_used_pmds[0],
+			ctx->ctx_saved_pmcs[0],
+			ctx->ctx_reload_pmcs[0]));
 
 	/*
-	 * XXX: need to record sample only when an EAR/BTB has overflowed
+	 * First we update the virtual counters
 	 */
-	if (CTX_HAS_SMPL(ctx)) {
-		pfm_smpl_buffer_desc_t *psb = ctx->ctx_smpl_buf;
-		unsigned long *e, m, idx=0;
-		perfmon_smpl_entry_t *h;
-		int j;
-
-		idx = ia64_fetch_and_add(1, &psb->psb_index);
-		DBprintk((" recording index=%ld entries=%ld\n", idx, psb->psb_entries));
+	for (i = PMU_FIRST_COUNTER; mask ; i++, mask >>= 1) {
+
+		/* skip pmd which did not overflow */
+		if ((mask & 0x1) == 0) continue;
+
+		DBprintk(("PMD[%d] overflowed hw_pmd=0x%lx soft_pmd=0x%lx\n", 
+			  i, ia64_get_pmd(i), ctx->ctx_soft_pmds[i].val));
 
 		/*
-		 * XXX: there is a small chance that we could run out on index before resetting
-		 * but index is unsigned long, so it will take some time.....
-		 * We use > instead of == because fetch_and_add() is off by one (see below)
-		 *
-		 * This case can happen in non-blocking mode or with multiple processes.
-		 * For non-blocking, we need to reload and continue.
+		 * Because we sometimes (EARS/BTB) reset to a specific value, we cannot simply use
+		 * val to count the number of times we overflowed. Otherwise we would loose the 
+		 * current value in the PMD (which can be >0). So to make sure we don't loose
+		 * the residual counts we set val to contain full 64bits value of the counter.
 		 */
-		if (idx > psb->psb_entries) {
-			buffer_is_full = 1;
-			goto reload_pmds;
-		}
-
-		/* first entry is really entry 0, not 1 caused by fetch_and_add */
-		idx--;
+		old_val = ctx->ctx_soft_pmds[i].val;
+		ctx->ctx_soft_pmds[i].val = 1 + pmu_conf.perf_ovfl_val + pfm_read_soft_counter(ctx, i);
 
-		h = (perfmon_smpl_entry_t *)(((char *)psb->psb_addr) + idx*(psb->psb_entry_size));
 
-		h->pid  = task->pid;
-		h->cpu  = my_cpu;
-		h->rate = 0;
-		h->ip   = regs ? regs->cr_iip : 0x0; /* where did the fault happened */
-		h->regs = mask; /* which registers overflowed */
+		DBprintk(("soft_pmd[%d].val=0x%lx old_val=0x%lx pmd=0x%lx\n", 
+			  i, ctx->ctx_soft_pmds[i].val, old_val, 
+			  ia64_get_pmd(i) & pmu_conf.perf_ovfl_val));
 
-		/* guaranteed to monotonically increase on each cpu */
-		h->stamp = perfmon_get_stamp();
-
-		e = (unsigned long *)(h+1);
-
-		/*
-		 * selectively store PMDs in increasing index number
-		 */
-		for (j=0, m = ctx->ctx_smpl_regs; m; m >>=1, j++) {
-			if (m & 0x1) {
-				if (PMD_IS_COUNTER(j))
-					*e =  ctx->ctx_pmds[j-PMU_FIRST_COUNTER].val
-					    + (ia64_get_pmd(j) & pmu_conf.perf_ovfl_val);
-				else {
-					*e = ia64_get_pmd(j); /* slow */
-				}
-				DBprintk((" e=%p pmd%d =0x%lx\n", (void *)e, j, *e));
-				e++;
-			}
-		}
 		/*
-		 * make the new entry visible to user, needs to be atomic
+		 * now that we have extracted the hardware counter, we can clear it to ensure
+		 * that a subsequent PFM_READ_PMDS will not include it again.
 		 */
-		ia64_fetch_and_add(1, &psb->psb_hdr->hdr_count);
+		ia64_set_pmd(i, 0UL);
 
-		DBprintk((" index=%ld entries=%ld hdr_count=%ld\n", idx, psb->psb_entries, psb->psb_hdr->hdr_count));
-		/* 
-		 * sampling buffer full ? 
+		/*
+		 * check for overflow condition
 		 */
-		if (idx == (psb->psb_entries-1)) {
-			/*
-			 * will cause notification, cannot be 0
-			 */
-			bv = mask << PMU_FIRST_COUNTER;
+		if (old_val > ctx->ctx_soft_pmds[i].val) {
 
-			buffer_is_full = 1;
+			ovfl_pmds |= 1UL << i;
 
-			DBprintk((" sampling buffer full must notify bv=0x%lx\n", bv));
+			DBprintk(("soft_pmd[%d] overflowed flags=0x%x, ovfl=0x%lx\n", i, ctx->ctx_soft_pmds[i].flags, ovfl_pmds));
 
-			/*
-			 * we do not reload here, when context is blocking
-			 */
-			if (!CTX_OVFL_NOBLOCK(ctx)) goto no_reload;
-
-			/*
-			 * here, we have a full buffer but we are in non-blocking mode
-			 * so we need to reload overflowed PMDs with sampling reset values
-			 * and restart right away.
-			 */
+			if (PMC_OVFL_NOTIFY(ctx, i)) {
+				ovfl_notify |= 1UL << i;
+			}
 		}
-		/* FALL THROUGH */
 	}
-reload_pmds:
-
-	/*
-	 * in the case of a non-blocking context, we reload
-	 * with the ovfl_rval when no user notification is taking place (short recovery)
-	 * otherwise when the buffer is full which requires user interaction) then we use
-	 * smpl_rval which is the long_recovery path (disturbance introduce by user execution).
-	 *
-	 * XXX: implies that when buffer is full then there is always notification.
-	 */
-	ovfl_has_long_recovery = CTX_OVFL_NOBLOCK(ctx) && buffer_is_full;
 
 	/*
-	 * XXX: CTX_HAS_SMPL() should really be something like CTX_HAS_SMPL() and is activated,i.e.,
-	 * one of the PMC is configured for EAR/BTB.
+	 * check for sampling buffer
 	 *
-	 * When sampling, we can only notify when the sampling buffer is full.
+	 * if present, record sample. We propagate notification ONLY when buffer
+	 * becomes full.
 	 */
-	can_notify   = CTX_HAS_SMPL(ctx) == 0 && ctx->ctx_notify_task;
-
-	DBprintk((" ovfl_has_long_recovery=%d can_notify=%d\n", ovfl_has_long_recovery, can_notify));
-
-	for (i = 0, cnum = PMU_FIRST_COUNTER; mask ; cnum++, i++, mask >>= 1) {
-
-		if ((mask & 0x1) == 0) continue;
-
-		DBprintk((" PMD[%ld] overflowed pmd=0x%lx pmod.val=0x%lx\n", cnum, ia64_get_pmd(cnum), ctx->ctx_pmds[i].val));
-
-		/*
-		 * Because we sometimes (EARS/BTB) reset to a specific value, we cannot simply use
-		 * val to count the number of times we overflowed. Otherwise we would loose the current value
-		 * in the PMD (which can be >0). So to make sure we don't loose
-		 * the residual counts we set val to contain full 64bits value of the counter.
-		 *
-		 * XXX: is this needed for EARS/BTB ?
-		 */
-		ctx->ctx_pmds[i].val += 1 + pmu_conf.perf_ovfl_val
-				      + (ia64_get_pmd(cnum) & pmu_conf.perf_ovfl_val); /* slow */
-
-		DBprintk((" pmod[%ld].val=0x%lx pmd=0x%lx\n", i, ctx->ctx_pmds[i].val, ia64_get_pmd(cnum)&pmu_conf.perf_ovfl_val));
-
-		if (can_notify && PMD_OVFL_NOTIFY(ctx, i)) {
-			DBprintk((" CPU%d should notify task %p with signal %d\n", my_cpu, ctx->ctx_notify_task, ctx->ctx_notify_sig));
-			bv |= 1 << i;
-		} else {
-			DBprintk((" CPU%d PMD[%ld] overflow, no notification\n", my_cpu, cnum));
+	if(CTX_HAS_SMPL(ctx)) {
+		ret = pfm_record_sample(task, ctx, ovfl_pmds, regs);
+		if (ret == 1) {
 			/*
-			 * In case no notification is requested, we reload the reset value right away
-			 * otherwise we wait until the notify_pid process has been called and has
-			 * has finished processing data. Check out pfm_overflow_notify()
+			 * Sampling buffer became full
+			 * If no notication was requested, then we reset buffer index
+			 * and reset registers (done below) and resume.
+			 * If notification requested, then defer reset until pfm_restart()
 			 */
-
-			/* writes to upper part are ignored, so this is safe */
-			if (ovfl_has_long_recovery) {
-				DBprintk((" CPU%d PMD[%ld] reload with smpl_val=%lx\n", my_cpu, cnum,ctx->ctx_pmds[i].smpl_rval));
-				ia64_set_pmd(cnum, ctx->ctx_pmds[i].smpl_rval);
-			} else {
-				DBprintk((" CPU%d PMD[%ld] reload with ovfl_val=%lx\n", my_cpu, cnum,ctx->ctx_pmds[i].smpl_rval));
-				ia64_set_pmd(cnum, ctx->ctx_pmds[i].ovfl_rval);
+			if (ovfl_notify == 0UL) {
+				ctx->ctx_psb->psb_hdr->hdr_count = 0UL;
+				ctx->ctx_psb->psb_index		 = 0UL;
 			}
+		} else {
+			/*
+			 * sample recorded in buffer, no need to notify user
+			 */
+			ovfl_notify = 0UL;
 		}
-		if (cnum == ctx->ctx_btb_counter) need_reset_pmd16=1;
 	}
-	/*
-	 * In case of BTB overflow we need to reset the BTB index.
-	 */
-	if (need_reset_pmd16) {
-		DBprintk(("reset PMD16\n"));
-		ia64_set_pmd(16, 0);
-	}
-
-no_reload:
 
 	/*
-	 * some counters overflowed, but they did not require
-	 * user notification, so after having reloaded them above
-	 * we simply restart
+	 * No overflow requiring a user level notification
 	 */
-	if (!bv) return 0x0;
+	if (ovfl_notify == 0UL) {
+		pfm_reset_regs(ctx, &ovfl_pmds, PFM_RELOAD_SHORT_RESET);
+		return 0x0;
+	}
 
-	ctx->ctx_ovfl_regs  = bv; /* keep track of what to reset when unblocking */
-	/*
-	 * Now we know that:
-	 * 	- we have some counters which overflowed (contains in bv)
-	 * 	- someone has asked to be notified on overflow. 
+	/* 
+	 * keep track of what to reset when unblocking 
 	 */
+	ctx->ctx_ovfl_regs[0]  = ovfl_pmds; 
 
-	
 	/*
-	 * If the notification task is still present, then notify_task is non
-	 * null. It is clean by that task if it ever exits before we do. 
+	 * we have come to this point because there was an overflow and that notification
+	 * was requested. The notify_task may have disappeared, in which case notify_task
+	 * is NULL.
 	 */
-
 	if (ctx->ctx_notify_task) {
 
 		si.si_errno    = 0;
 		si.si_addr     = NULL;
 		si.si_pid      = task->pid; /* who is sending */
 
-		si.si_signo    = ctx->ctx_notify_sig; /* is SIGPROF */
-		si.si_code     = PROF_OVFL; /* goes to user */
-		si.si_pfm_ovfl = bv;
-
-
+		si.si_signo    = SIGPROF;
+		si.si_code     = PROF_OVFL; /* indicates a perfmon SIGPROF signal */
+		/*
+		 * Shift the bitvector such that the user sees bit 4 for PMD4 and so on.
+		 * We only use smpl_ovfl[0] for now. It should be fine for quite a while
+		 * until we have more than 61 PMD available.
+		 */
+		si.si_pfm_ovfl[0] = ovfl_notify;
 	
 		/*
 		 * when the target of the signal is not ourself, we have to be more
@@ -1659,15 +2648,29 @@
 		if (ctx->ctx_notify_task != current) {
 			/*
 			 * grab the notification lock for this task
+			 * This guarantees that the sequence: test + send_signal
+			 * is atomic with regards to the ctx_notify_task field.
+			 *
+			 * We need a spinlock and not just an atomic variable for this.
+			 *
 			 */
-			spin_lock(&ctx->ctx_notify_lock);
+			spin_lock(&ctx->ctx_lock);
 
 			/*
 			 * now notify_task cannot be modified until we're done
 			 * if NULL, they it got modified while we were in the handler
 			 */
 			if (ctx->ctx_notify_task == NULL) {
-				spin_unlock(&ctx->ctx_notify_lock);
+
+				spin_unlock(&ctx->ctx_lock);
+
+				/*
+				 * If we've lost the notified task, then we will run
+				 * to completion wbut keep the PMU frozen. Results
+				 * will be incorrect anyway. We do not kill task
+				 * to leave it possible to attach perfmon context
+				 * to already running task.
+				 */
 				goto lost_notify;
 			}
 			/*
@@ -1681,20 +2684,23 @@
 	 	 * necessarily go to the signal handler (if any) when it goes back to
 	 	 * user mode.
 	 	 */
-		DBprintk((" %d sending %d notification to %d\n", task->pid, si.si_signo, ctx->ctx_notify_task->pid));
+		DBprintk(("[%d] sending notification to [%d]\n", 
+			  task->pid, ctx->ctx_notify_task->pid));
 
 
 		/* 
 		 * this call is safe in an interrupt handler, so does read_lock() on tasklist_lock
 		 */
-		ret = send_sig_info(ctx->ctx_notify_sig, &si, ctx->ctx_notify_task);
-		if (ret != 0) printk(" send_sig_info(process %d, SIGPROF)=%d\n",  ctx->ctx_notify_task->pid, ret);
+		ret = send_sig_info(SIGPROF, &si, ctx->ctx_notify_task);
+		if (ret != 0) 
+			printk("send_sig_info(process %d, SIGPROF)=%d\n",  
+			       ctx->ctx_notify_task->pid, ret);
 		/*
 		 * now undo the protections in order
 		 */
 		if (ctx->ctx_notify_task != current) {
 			read_unlock(&tasklist_lock);
-			spin_unlock(&ctx->ctx_notify_lock);
+			spin_unlock(&ctx->ctx_lock);
 		}
 
 		/*
@@ -1711,35 +2717,41 @@
 		 * before, changing it to NULL will still maintain this invariant.
 		 * Of course, when it is equal to current it cannot change at this point.
 		 */
-		if (!CTX_OVFL_NOBLOCK(ctx) && ctx->ctx_notify_task != current) {
-				th->pfm_must_block = 1; /* will cause blocking */
+		DBprintk(("block=%d notify [%d] current [%d]\n", 
+			ctx->ctx_fl_block,
+			ctx->ctx_notify_task ? ctx->ctx_notify_task->pid: -1, 
+			current->pid ));
+
+		if (!CTX_OVFL_NOBLOCK(ctx) && ctx->ctx_notify_task != task) {
+			t->pfm_ovfl_block_reset = 1; /* will cause blocking */
 		}
 	} else {
-lost_notify:
-		DBprintk((" notification task has disappeared !\n"));
+lost_notify: /* XXX: more to do here, to convert to non-blocking (reset values) */
+
+		DBprintk(("notification task has disappeared !\n"));
 		/*
-		 * for a non-blocking context, we make sure we do not fall into the pfm_overflow_notify()
-		 * trap. Also in the case of a blocking context with lost notify process, then we do not
-		 * want to block either (even though it is interruptible). In this case, the PMU will be kept
-		 * frozen and the process will run to completion without monitoring enabled.
+		 * for a non-blocking context, we make sure we do not fall into the 
+		 * pfm_overflow_notify() trap. Also in the case of a blocking context with lost 
+		 * notify process, then we do not want to block either (even though it is 
+		 * interruptible). In this case, the PMU will be kept frozen and the process will 
+		 * run to completion without monitoring enabled.
 		 *
 		 * Of course, we cannot loose notify process when self-monitoring.
 		 */
-		th->pfm_must_block = 0; 
+		t->pfm_ovfl_block_reset = 0; 
 
 	}
 	/*
-	 * if we block, we keep the PMU frozen. If non-blocking we restart.
-	 * in the case of non-blocking were the notify process is lost, we also 
-	 * restart. 
+	 * If notification was successful, then we rely on the pfm_restart()
+	 * call to unfreeze and reset (in both blocking or non-blocking mode).
+	 *
+	 * If notification failed, then we will keep the PMU frozen and run
+	 * the task to completion
 	 */
-	if (!CTX_OVFL_NOBLOCK(ctx)) 
-		ctx->ctx_fl_frozen  = 1;
-	else
-		ctx->ctx_fl_frozen = 0;
+	ctx->ctx_fl_frozen = 1;
 
-	DBprintk((" reload pmc0=0x%x must_block=%ld\n",
-				ctx->ctx_fl_frozen ? 0x1 : 0x0, th->pfm_must_block));
+	DBprintk(("reload pmc0=0x%x must_block=%ld\n",
+				ctx->ctx_fl_frozen ? 0x1 : 0x0, t->pfm_ovfl_block_reset));
 
 	return ctx->ctx_fl_frozen ? 0x1 : 0x0;
 }
@@ -1748,29 +2760,40 @@
 perfmon_interrupt (int irq, void *arg, struct pt_regs *regs)
 {
 	u64 pmc0;
-	struct task_struct *ta;
+	struct task_struct *task;
 
-	pmc0 = ia64_get_pmc(0); /* slow */
+	pfm_ovfl_intr_count++;
+
+	/* 
+	 * srlz.d done before arriving here
+	 *
+	 * This is slow
+	 */
+	pmc0 = ia64_get_pmc(0); 
 
 	/*
 	 * if we have some pending bits set
 	 * assumes : if any PM[0].bit[63-1] is set, then PMC[0].fr = 1
 	 */
-	if ((pmc0 & ~0x1) && (ta=PMU_OWNER())) {
+	if ((pmc0 & ~0x1UL)!=0UL && (task=PMU_OWNER())!= NULL) {
 
-		/* assumes, PMC[0].fr = 1 at this point */
-		pmc0 = update_counters(ta, pmc0, regs);
-
-		/*
-		 * if pmu_frozen = 0
-		 *	pmc0 = 0 and we resume monitoring right away
-		 * else
-		 *	pmc0 = 0x1 frozen but all pending bits are cleared
+		/* 
+		 * assumes, PMC[0].fr = 1 at this point 
+		 *
+		 * XXX: change protype to pass &pmc0
 		 */
-		ia64_set_pmc(0, pmc0);
-		ia64_srlz_d();
+		pmc0 = pfm_overflow_handler(task, pmc0, regs);
+
+		/* we never explicitely freeze PMU here */
+		if (pmc0 == 0) {
+			ia64_set_pmc(0, 0);
+			ia64_srlz_d();
+		}
 	} else {
-		printk("perfmon: Spurious PMU overflow interrupt: pmc0=0x%lx owner=%p\n", pmc0, (void *)PMU_OWNER());
+		pfm_spurious_ovfl_intr_count++;
+
+		DBprintk(("perfmon: Spurious PMU overflow interrupt on CPU%d: pmc0=0x%lx owner=%p\n", 
+			smp_processor_id(), pmc0, (void *)PMU_OWNER()));
 	}
 }
 
@@ -1778,14 +2801,39 @@
 static int
 perfmon_proc_info(char *page)
 {
+#ifdef CONFIG_SMP
+#define cpu_is_online(i) (cpu_online_map & (1UL << i))
+#else
+#define cpu_is_online(i)        1
+#endif
 	char *p = page;
 	u64 pmc0 = ia64_get_pmc(0);
 	int i;
 
-	p += sprintf(p, "CPU%d.pmc[0]=%lx\nPerfmon debug: %s\n", smp_processor_id(), pmc0, pfm_debug ? "On" : "Off");
-	p += sprintf(p, "proc_sessions=%lu sys_sessions=%lu\n", 
-			pfs_info.pfs_proc_sessions, 
-			pfs_info.pfs_sys_session);
+	p += sprintf(p, "perfmon enabled: %s\n", pmu_conf.pfm_is_disabled ? "No": "Yes");
+
+	p += sprintf(p, "monitors_pmcs0]=0x%lx\n", pmu_conf.monitor_pmcs[0]);
+	p += sprintf(p, "counter_pmct pfm_+	 * Thy_tast: pmc0=.)
+ * 	1 : buffer is full (mu_conf.monitor_pmcs[0]);
+	p +<06k to thmu_conf 0]);
+	p += sprintf(p, "counter_pmct ps full (mu_conf.mpl_rval))o thmu_conf\n", smp_long
-update_counterug ?/
-	*user_addr = (n", f\n",for (i =	} elsthe tasreset _cpu, smp_pate_counterug ?/
-	leeping r+	 * keep t*)psb->	if (can_ounteru()
 			 */
-
-			/* ll:
-	if (child != current) read_D_ARG_MANY	-1 /* cannot be zerod_D_ARG_MANY	+1	 * wan+= drivers/sgi/sgi.a
@@ -185if (child != current) read_D;
+			  *ta;
+	sPFM_P			 *aIn case no notification is requested, we ounts we set vwe ounts we senew methng data. Che */
-
mu_co
+
+	p += sprintf(p,(&s[0]  =#define DBR_t has 1)) goto no_reload;
-
-			this riIS_ENABLED(ctxal); /*d ? "No": "Yes");n", my_cpu, cnupmc00]);
+	p ing v someone has asked t.val=0x%lx erfmopmcs[0]);
+	p += sprintf(p, "counter_pmct pfm_+	 * Thy_tast: pmc0=.)
+ * 	1 : buffer is full (mu_conf.monitor_pmcs[0]);
+	p +<06k to thmu_conf 0]);
+	p += sprintf(p,1 counters.
 			 */
-			Yes");n", mt buffer index
+			 * a		ret =pmct p.pfr_rog,t this right now ontinue;
 (task != current) return -EINVAL;
+	);
+ task if it ever exits befor)fpt: pmcsomeone has asked t.val=0x%l{
+		+ilear it to ensure
+	
-			this riIS_ENABLED(ctxal)R)/inum)&pmu;
-		rify_tasr now. I": "Yes[i].smpl_igned lms {
 
-((" CPU%d %ious ovePFM_CMD_IS_. Che */
al when no user notification,gnter
+	int el to count thehe user srrintf(pÛ